Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r40e636a r679864e1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Validate.cc --
     7// Validate.cc -- 
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 12 17:49:21 2016
    13 // Update Count     : 298
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Oct 06 15:40:35 2015
     13// Update Count     : 219
    1414//
    1515
     
    4040#include <list>
    4141#include <iterator>
    42 #include "Common/utility.h"
    43 #include "Common/UniqueName.h"
    4442#include "Validate.h"
    4543#include "SynTree/Visitor.h"
    4644#include "SynTree/Mutator.h"
    4745#include "SynTree/Type.h"
    48 #include "SynTree/Expression.h"
    4946#include "SynTree/Statement.h"
    5047#include "SynTree/TypeSubstitution.h"
     
    5249#include "FixFunction.h"
    5350// #include "ImplementationType.h"
    54 #include "GenPoly/DeclMutator.h"
     51#include "utility.h"
     52#include "UniqueName.h"
    5553#include "AddVisit.h"
    5654#include "MakeLibCfa.h"
    5755#include "TypeEquality.h"
    58 #include "Autogen.h"
    59 #include "ResolvExpr/typeops.h"
    6056
    6157#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    6662                /// Flattens nested struct types
    6763                static void hoistStruct( std::list< Declaration * > &translationUnit );
    68 
     64 
    6965                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    70 
     66 
    7167                virtual void visit( StructDecl *aggregateDecl );
    7268                virtual void visit( UnionDecl *aggregateDecl );
    7369
    7470                virtual void visit( CompoundStmt *compoundStmt );
     71                virtual void visit( IfStmt *ifStmt );
     72                virtual void visit( WhileStmt *whileStmt );
     73                virtual void visit( ForStmt *forStmt );
    7574                virtual void visit( SwitchStmt *switchStmt );
     75                virtual void visit( ChooseStmt *chooseStmt );
     76                virtual void visit( CaseStmt *caseStmt );
     77                virtual void visit( CatchStmt *catchStmt );
    7678          private:
    7779                HoistStruct();
     
    8385        };
    8486
    85         /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
     87        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers
    8688        class Pass1 : public Visitor {
    8789                typedef Visitor Parent;
     
    98100                virtual void visit( StructInstType *structInst );
    99101                virtual void visit( UnionInstType *unionInst );
    100                 virtual void visit( TraitInstType *contextInst );
     102                virtual void visit( ContextInstType *contextInst );
    101103                virtual void visit( StructDecl *structDecl );
    102104                virtual void visit( UnionDecl *unionDecl );
     
    104106
    105107                const Indexer *indexer;
    106 
     108 
    107109                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    108110                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     
    123125        };
    124126
    125         class ReturnChecker : public Visitor {
     127        class AddStructAssignment : public Visitor {
    126128          public:
    127                 /// Checks that return statements return nothing if their return type is void
    128                 /// and return something if the return type is non-void.
    129                 static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
     129                /// Generates assignment operators for aggregate types as required
     130                static void addStructAssignment( std::list< Declaration * > &translationUnit );
     131
     132                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     133 
     134                virtual void visit( EnumDecl *enumDecl );
     135                virtual void visit( StructDecl *structDecl );
     136                virtual void visit( UnionDecl *structDecl );
     137                virtual void visit( TypeDecl *typeDecl );
     138                virtual void visit( ContextDecl *ctxDecl );
     139                virtual void visit( FunctionDecl *functionDecl );
     140
     141                virtual void visit( FunctionType *ftype );
     142                virtual void visit( PointerType *ftype );
     143 
     144                virtual void visit( CompoundStmt *compoundStmt );
     145                virtual void visit( IfStmt *ifStmt );
     146                virtual void visit( WhileStmt *whileStmt );
     147                virtual void visit( ForStmt *forStmt );
     148                virtual void visit( SwitchStmt *switchStmt );
     149                virtual void visit( ChooseStmt *chooseStmt );
     150                virtual void visit( CaseStmt *caseStmt );
     151                virtual void visit( CatchStmt *catchStmt );
     152
     153                AddStructAssignment() : functionNesting( 0 ) {}
    130154          private:
    131                 virtual void visit( FunctionDecl * functionDecl );
    132 
    133                 virtual void visit( ReturnStmt * returnStmt );
    134 
    135                 std::list< DeclarationWithType * > returnVals;
     155                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     156 
     157                std::list< Declaration * > declsToAdd;
     158                std::set< std::string > structsDone;
     159                unsigned int functionNesting;                   // current level of nested functions
    136160        };
    137161
    138162        class EliminateTypedef : public Mutator {
    139163          public:
    140                 EliminateTypedef() : scopeLevel( 0 ) {}
    141                 /// Replaces typedefs by forward declarations
     164          EliminateTypedef() : scopeLevel( 0 ) {}
     165            /// Replaces typedefs by forward declarations
    142166                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    143167          private:
     
    153177                virtual Declaration *mutate( UnionDecl * unionDecl );
    154178                virtual Declaration *mutate( EnumDecl * enumDecl );
    155                 virtual Declaration *mutate( TraitDecl * contextDecl );
     179                virtual Declaration *mutate( ContextDecl * contextDecl );
    156180
    157181                template<typename AggDecl>
    158182                AggDecl *handleAggregate( AggDecl * aggDecl );
    159183
    160                 template<typename AggDecl>
    161                 void addImplicitTypedef( AggDecl * aggDecl );
    162 
    163184                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
     185                typedef std::map< std::string, TypeDecl * > TypeDeclMap;
    164186                TypedefMap typedefNames;
     187                TypeDeclMap typedeclNames;
    165188                int scopeLevel;
    166         };
    167 
    168         class VerifyCtorDtor : public Visitor {
    169         public:
    170                 /// ensure that constructors and destructors have at least one
    171                 /// parameter, the first of which must be a pointer, and no
    172                 /// return values.
    173                 static void verify( std::list< Declaration * > &translationUnit );
    174 
    175                 virtual void visit( FunctionDecl *funcDecl );
    176         };
    177 
    178         class CompoundLiteral : public GenPoly::DeclMutator {
    179                 DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass;
    180 
    181                 virtual DeclarationWithType * mutate( ObjectDecl *objectDecl );
    182                 virtual Expression *mutate( CompoundLiteralExpr *compLitExpr );
    183189        };
    184190
     
    187193                Pass2 pass2( doDebug, 0 );
    188194                Pass3 pass3( 0 );
    189                 CompoundLiteral compoundliteral;
    190 
    191195                EliminateTypedef::eliminateTypedef( translationUnit );
    192196                HoistStruct::hoistStruct( translationUnit );
    193                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1
    194197                acceptAll( translationUnit, pass1 );
    195198                acceptAll( translationUnit, pass2 );
    196                 ReturnChecker::checkFunctionReturns( translationUnit );
    197                 compoundliteral.mutateDeclarationList( translationUnit );
     199                // need to collect all of the assignment operators prior to
     200                // this point and only generate assignment operators if one doesn't exist
     201                AddStructAssignment::addStructAssignment( translationUnit );
    198202                acceptAll( translationUnit, pass3 );
    199                 VerifyCtorDtor::verify( translationUnit );
    200         }
    201 
     203        }
     204       
    202205        void validateType( Type *type, const Indexer *indexer ) {
    203206                Pass1 pass1;
     
    207210                type->accept( pass2 );
    208211                type->accept( pass3 );
     212        }
     213
     214        template< typename Visitor >
     215        void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     216                std::list< Declaration * >::iterator i = translationUnit.begin();
     217                while ( i != translationUnit.end() ) {
     218                        (*i)->accept( visitor );
     219                        std::list< Declaration * >::iterator next = i;
     220                        next++;
     221                        if ( ! visitor.get_declsToAdd().empty() ) {
     222                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     223                        } // if
     224                        i = next;
     225                } // while
    209226        }
    210227
     
    263280        }
    264281
     282        void HoistStruct::visit( IfStmt *ifStmt ) {
     283                addVisit( ifStmt, *this );
     284        }
     285
     286        void HoistStruct::visit( WhileStmt *whileStmt ) {
     287                addVisit( whileStmt, *this );
     288        }
     289
     290        void HoistStruct::visit( ForStmt *forStmt ) {
     291                addVisit( forStmt, *this );
     292        }
     293
    265294        void HoistStruct::visit( SwitchStmt *switchStmt ) {
    266295                addVisit( switchStmt, *this );
    267296        }
    268297
     298        void HoistStruct::visit( ChooseStmt *switchStmt ) {
     299                addVisit( switchStmt, *this );
     300        }
     301
     302        void HoistStruct::visit( CaseStmt *caseStmt ) {
     303                addVisit( caseStmt, *this );
     304        }
     305
     306        void HoistStruct::visit( CatchStmt *cathStmt ) {
     307                addVisit( cathStmt, *this );
     308        }
     309
    269310        void Pass1::visit( EnumDecl *enumDecl ) {
    270311                // Set the type of each member of the enumeration to be EnumConstant
     312 
    271313                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    272314                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    273315                        assert( obj );
    274                         obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
     316                        // obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
     317                        BasicType * enumType = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     318                        obj->set_type( enumType ) ;
    275319                } // for
    276320                Parent::visit( enumDecl );
     
    278322
    279323        namespace {
    280                 template< typename DWTList >
    281                 void fixFunctionList( DWTList & dwts, FunctionType * func ) {
     324                template< typename DWTIterator >
     325                void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
    282326                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    283327                        // entirely other fix ups are handled by the FixFunction class
    284                         typedef typename DWTList::iterator DWTIterator;
    285                         DWTIterator begin( dwts.begin() ), end( dwts.end() );
    286328                        if ( begin == end ) return;
    287329                        FixFunction fixer;
    288330                        DWTIterator i = begin;
    289                         *i = (*i)->acceptMutator( fixer );
     331                        *i = (*i )->acceptMutator( fixer );
    290332                        if ( fixer.get_isVoid() ) {
    291333                                DWTIterator j = i;
    292334                                ++i;
    293                                 dwts.erase( j );
    294                                 if ( i != end ) {
     335                                func->get_parameters().erase( j );
     336                                if ( i != end ) { 
    295337                                        throw SemanticError( "invalid type void in function type ", func );
    296338                                } // if
     
    310352        void Pass1::visit( FunctionType *func ) {
    311353                // Fix up parameters and return types
    312                 fixFunctionList( func->get_parameters(), func );
    313                 fixFunctionList( func->get_returnVals(), func );
     354                fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
     355                fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
    314356                Visitor::visit( func );
    315357        }
     
    328370                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    329371                if ( st ) {
    330                         //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
     372                        assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
    331373                        structInst->set_baseStruct( st );
    332374                } // if
     
    350392        }
    351393
    352         void Pass2::visit( TraitInstType *contextInst ) {
     394        void Pass2::visit( ContextInstType *contextInst ) {
    353395                Parent::visit( contextInst );
    354                 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
     396                ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
    355397                if ( ! ctx ) {
    356398                        throw SemanticError( "use of undeclared context " + contextInst->get_name() );
     
    358400                for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    359401                        for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    360                                 if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
     402                                if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
    361403                                        cloneAll( otherCtx->get_members(), contextInst->get_members() );
    362404                                } else {
     
    374416
    375417        void Pass2::visit( StructDecl *structDecl ) {
    376                 // visit struct members first so that the types of self-referencing members are updated properly
    377                 Parent::visit( structDecl );
    378418                if ( ! structDecl->get_members().empty() ) {
    379419                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     
    385425                        } // if
    386426                } // if
     427                Indexer::visit( structDecl );
    387428        }
    388429
    389430        void Pass2::visit( UnionDecl *unionDecl ) {
    390                 Parent::visit( unionDecl );
    391431                if ( ! unionDecl->get_members().empty() ) {
    392432                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     
    398438                        } // if
    399439                } // if
     440                Indexer::visit( unionDecl );
    400441        }
    401442
     
    423464                        while ( ! toBeDone.empty() ) {
    424465                                for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    425                                         if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
     466                                        if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
    426467                                                for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    427468                                                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
     
    460501        }
    461502
    462         void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    463                 ReturnChecker checker;
    464                 acceptAll( translationUnit, checker );
    465         }
    466 
    467         void ReturnChecker::visit( FunctionDecl * functionDecl ) {
    468                 std::list< DeclarationWithType * > oldReturnVals = returnVals;
    469                 returnVals = functionDecl->get_functionType()->get_returnVals();
    470                 Visitor::visit( functionDecl );
    471                 returnVals = oldReturnVals;
    472         }
    473 
    474         void ReturnChecker::visit( ReturnStmt * returnStmt ) {
    475                 // Previously this also checked for the existence of an expr paired with no return values on
    476                 // the  function return type. This is incorrect, since you can have an expression attached to
    477                 // a return statement in a void-returning function in C. The expression is treated as if it
    478                 // were cast to void.
    479                 if ( returnStmt->get_expr() == NULL && returnVals.size() != 0 ) {
    480                         throw SemanticError( "Non-void function returns no values: " , returnStmt );
     503        static const std::list< std::string > noLabels;
     504
     505        void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
     506                AddStructAssignment visitor;
     507                acceptAndAdd( translationUnit, visitor, false );
     508        }
     509
     510        template< typename OutputIterator >
     511        void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
     512                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
     513                // unnamed bit fields are not copied as they cannot be accessed
     514                if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
     515
     516                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     517 
     518                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     519                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     520 
     521                // do something special for unnamed members
     522                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
     523                assignExpr->get_args().push_back( dstselect );
     524 
     525                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     526                assignExpr->get_args().push_back( srcselect );
     527 
     528                *out++ = new ExprStmt( noLabels, assignExpr );
     529        }
     530
     531        template< typename OutputIterator >
     532        void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
     533                static UniqueName indexName( "_index" );
     534 
     535                // for a flexible array member nothing is done -- user must define own assignment
     536                if ( ! array->get_dimension() ) return;
     537 
     538                ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
     539                *out++ = new DeclStmt( noLabels, index );
     540 
     541                UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
     542                init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     543                init->get_args().push_back( new NameExpr( "0" ) );
     544                Statement *initStmt = new ExprStmt( noLabels, init );
     545                std::list<Statement *> initList;
     546                initList.push_back( initStmt );
     547 
     548                UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
     549                cond->get_args().push_back( new VariableExpr( index ) );
     550                cond->get_args().push_back( array->get_dimension()->clone() );
     551 
     552                UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
     553                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     554 
     555                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     556 
     557                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     558                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     559 
     560                Expression *dstselect = new MemberExpr( member, derefExpr );
     561                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
     562                dstIndex->get_args().push_back( dstselect );
     563                dstIndex->get_args().push_back( new VariableExpr( index ) );
     564                assignExpr->get_args().push_back( dstIndex );
     565 
     566                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     567                UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     568                srcIndex->get_args().push_back( srcselect );
     569                srcIndex->get_args().push_back( new VariableExpr( index ) );
     570                assignExpr->get_args().push_back( srcIndex );
     571 
     572                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
     573        }
     574
     575        //E ?=?(E volatile*, int),
     576        //  ?=?(E _Atomic volatile*, int);
     577        void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
     578                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     579 
     580                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     581                assignType->get_returnVals().push_back( returnVal );
     582
     583                // need two assignment operators with different types
     584                FunctionType * assignType2 = assignType->clone();
     585
     586                // E ?=?(E volatile *, E)
     587                Type *etype = refType->clone();
     588                // etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
     589
     590                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
     591                assignType->get_parameters().push_back( dstParam );
     592
     593                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
     594                assignType->get_parameters().push_back( srcParam );
     595
     596                // E ?=?(E volatile *, int)
     597                assignType2->get_parameters().push_back( dstParam->clone() );
     598                BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
     599                ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
     600                assignType2->get_parameters().push_back( srcParam2 );
     601
     602                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     603                // because each unit generates copies of the default routines for each aggregate.
     604
     605                // since there is no definition, these should not be inline
     606                // make these intrinsic so that the code generator does not make use of them
     607                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
     608                assignDecl->fixUniqueId();
     609                FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
     610                assignDecl2->fixUniqueId();
     611
     612                // these should be built in the same way that the prelude
     613                // functions are, so build a list containing the prototypes
     614                // and allow MakeLibCfa to autogenerate the bodies.
     615                std::list< Declaration * > assigns;
     616                assigns.push_back( assignDecl );
     617                assigns.push_back( assignDecl2 );
     618
     619                LibCfa::makeLibCfa( assigns );
     620
     621                // need to remove the prototypes, since this may be nested in a routine
     622                for (int start = 0, end = assigns.size()/2; start < end; start++) {
     623                        delete assigns.front();
     624                        assigns.pop_front();
     625                } // for
     626
     627                declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
     628        }
     629
     630
     631        Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
     632                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     633 
     634                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     635                assignType->get_returnVals().push_back( returnVal );
     636 
     637                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     638                assignType->get_parameters().push_back( dstParam );
     639 
     640                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     641                assignType->get_parameters().push_back( srcParam );
     642
     643                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     644                // because each unit generates copies of the default routines for each aggregate.
     645                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
     646                assignDecl->fixUniqueId();
     647 
     648                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
     649                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     650                                // query the type qualifiers of this field and skip assigning it if it is marked const.
     651                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
     652                                Type * type = dwt->get_type();
     653                                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     654                                        type = at->get_base();
     655                                }
     656
     657                                if ( type->get_qualifiers().isConst ) {
     658                                        // don't assign const members
     659                                        continue;
     660                                }
     661
     662                                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
     663                                        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     664                                } else {
     665                                        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     666                                } // if
     667                        } // if
     668                } // for
     669                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     670 
     671                return assignDecl;
     672        }
     673
     674        Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
     675                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     676 
     677                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     678                assignType->get_returnVals().push_back( returnVal );
     679 
     680                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     681                assignType->get_parameters().push_back( dstParam );
     682 
     683                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     684                assignType->get_parameters().push_back( srcParam );
     685 
     686                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     687                // because each unit generates copies of the default routines for each aggregate.
     688                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
     689                assignDecl->fixUniqueId();
     690 
     691                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
     692                copy->get_args().push_back( new VariableExpr( dstParam ) );
     693                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
     694                copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
     695
     696                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
     697                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     698 
     699                return assignDecl;
     700        }
     701
     702        void AddStructAssignment::visit( EnumDecl *enumDecl ) {
     703                if ( ! enumDecl->get_members().empty() ) {
     704                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
     705                        // enumInst->set_baseEnum( enumDecl );
     706                        // declsToAdd.push_back(
     707                        makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    481708                }
    482709        }
    483710
     711        void AddStructAssignment::visit( StructDecl *structDecl ) {
     712                if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
     713                        StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     714                        structInst->set_baseStruct( structDecl );
     715                        declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
     716                        structsDone.insert( structDecl->get_name() );
     717                } // if
     718        }
     719
     720        void AddStructAssignment::visit( UnionDecl *unionDecl ) {
     721                if ( ! unionDecl->get_members().empty() ) {
     722                        UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     723                        unionInst->set_baseUnion( unionDecl );
     724                        declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
     725                } // if
     726        }
     727
     728        void AddStructAssignment::visit( TypeDecl *typeDecl ) {
     729                CompoundStmt *stmts = 0;
     730                TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     731                typeInst->set_baseType( typeDecl );
     732                ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
     733                ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
     734                if ( typeDecl->get_base() ) {
     735                        stmts = new CompoundStmt( std::list< Label >() );
     736                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     737                        assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
     738                        assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
     739                        stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
     740                } // if
     741                FunctionType *type = new FunctionType( Type::Qualifiers(), false );
     742                type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
     743                type->get_parameters().push_back( dst );
     744                type->get_parameters().push_back( src );
     745                FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
     746                declsToAdd.push_back( func );
     747        }
     748
     749        void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
     750                for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
     751                        statements.insert( i, new DeclStmt( noLabels, *decl ) );
     752                } // for
     753                declsToAdd.clear();
     754        }
     755
     756        void AddStructAssignment::visit( FunctionType *) {
     757                // ensure that we don't add assignment ops for types defined as part of the function
     758        }
     759
     760        void AddStructAssignment::visit( PointerType *) {
     761                // ensure that we don't add assignment ops for types defined as part of the pointer
     762        }
     763
     764        void AddStructAssignment::visit( ContextDecl *) {
     765                // ensure that we don't add assignment ops for types defined as part of the context
     766        }
     767
     768        template< typename StmtClass >
     769        inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
     770                std::set< std::string > oldStructs = structsDone;
     771                addVisit( stmt, *this );
     772                structsDone = oldStructs;
     773        }
     774
     775        void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
     776                maybeAccept( functionDecl->get_functionType(), *this );
     777                acceptAll( functionDecl->get_oldDecls(), *this );
     778                functionNesting += 1;
     779                maybeAccept( functionDecl->get_statements(), *this );
     780                functionNesting -= 1;
     781        }
     782
     783        void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
     784                visitStatement( compoundStmt );
     785        }
     786
     787        void AddStructAssignment::visit( IfStmt *ifStmt ) {
     788                visitStatement( ifStmt );
     789        }
     790
     791        void AddStructAssignment::visit( WhileStmt *whileStmt ) {
     792                visitStatement( whileStmt );
     793        }
     794
     795        void AddStructAssignment::visit( ForStmt *forStmt ) {
     796                visitStatement( forStmt );
     797        }
     798
     799        void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
     800                visitStatement( switchStmt );
     801        }
     802
     803        void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
     804                visitStatement( switchStmt );
     805        }
     806
     807        void AddStructAssignment::visit( CaseStmt *caseStmt ) {
     808                visitStatement( caseStmt );
     809        }
     810
     811        void AddStructAssignment::visit( CatchStmt *cathStmt ) {
     812                visitStatement( cathStmt );
     813        }
    484814
    485815        bool isTypedef( Declaration *decl ) {
     
    490820                EliminateTypedef eliminator;
    491821                mutateAll( translationUnit, eliminator );
    492                 if ( eliminator.typedefNames.count( "size_t" ) ) {
    493                         // grab and remember declaration of size_t
    494                         SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();
    495                 } else {
    496                         // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
    497                         // eventually should have a warning for this case.
    498                         SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    499                 }
    500822                filter( translationUnit, isTypedef, true );
    501 
    502823        }
    503824
    504825        Type *EliminateTypedef::mutate( TypeInstType * typeInst ) {
    505                 // instances of typedef types will come here. If it is an instance
     826                // instances of typedef types will come here. If it is an instance 
    506827                // of a typdef type, link the instance to its actual type.
    507828                TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     
    516837                                }
    517838                                rtt->get_parameters().clear();
    518                                 cloneAll( typeInst->get_parameters(), rtt->get_parameters() );
    519                                 mutateAll( rtt->get_parameters(), *this );  // recursively fix typedefs on parameters
     839                                cloneAll(typeInst->get_parameters(), rtt->get_parameters());
    520840                        } // if
    521841                        delete typeInst;
    522842                        return ret;
     843                } else {
     844                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
     845                        assert( base != typedeclNames.end() );
     846                        typeInst->set_baseType( base->second->clone() );
    523847                } // if
    524848                return typeInst;
     
    527851        Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    528852                Declaration *ret = Mutator::mutate( tyDecl );
    529 
    530853                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    531                         // typedef to the same name from the same scope
     854                        // typedef to the same name from the same scope 
    532855                        // must be from the same type
    533856
    534857                        Type * t1 = tyDecl->get_base();
    535858                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    536                         if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
     859                        if ( ! typeEquals( t1, t2, true ) ) {
    537860                                throw SemanticError( "cannot redefine typedef: " + tyDecl->get_name() );
    538861                        }
     
    553876                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
    554877                        return new UnionDecl( aggDecl->get_name() );
    555                 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( tyDecl->get_base() ) ) {
    556                         return new EnumDecl( enumDecl->get_name() );
    557878                } else {
    558879                        return ret;
     
    565886                        typedefNames.erase( i ) ;
    566887                } // if
     888
     889                typedeclNames[ typeDecl->get_name() ] = typeDecl;
    567890                return typeDecl;
    568891        }
     
    579902                DeclarationWithType *ret = Mutator::mutate( objDecl );
    580903                typedefNames = oldNames;
    581                 // is the type a function?
    582904                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) {
    583                         // replace the current object declaration with a function declaration
    584905                        return new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn() );
    585906                } else if ( objDecl->get_isInline() || objDecl->get_isNoreturn() ) {
     
    616937        }
    617938
    618         // there may be typedefs nested within aggregates in order for everything to work properly, these should be removed
    619         // as well
     939        // there may be typedefs nested within aggregates
     940        // in order for everything to work properly, these
     941        // should be removed as well
    620942        template<typename AggDecl>
    621943        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
     
    632954        }
    633955
    634         template<typename AggDecl>
    635         void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
    636                 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
    637                         Type *type;
    638                         if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) {
    639                                 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() );
    640                         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( aggDecl ) ) {
    641                                 type = new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() );
    642                         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( aggDecl )  ) {
    643                                 type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
    644                         } // if
    645                         TypedefDecl * tyDecl = new TypedefDecl( aggDecl->get_name(), DeclarationNode::NoStorageClass, type );
    646                         typedefNames[ aggDecl->get_name() ] = std::make_pair( tyDecl, scopeLevel );
    647                 } // if
    648         }
    649 
    650956        Declaration *EliminateTypedef::mutate( StructDecl * structDecl ) {
    651                 addImplicitTypedef( structDecl );
    652957                Mutator::mutate( structDecl );
    653958                return handleAggregate( structDecl );
     
    655960
    656961        Declaration *EliminateTypedef::mutate( UnionDecl * unionDecl ) {
    657                 addImplicitTypedef( unionDecl );
    658962                Mutator::mutate( unionDecl );
    659963                return handleAggregate( unionDecl );
     
    661965
    662966        Declaration *EliminateTypedef::mutate( EnumDecl * enumDecl ) {
    663                 addImplicitTypedef( enumDecl );
    664967                Mutator::mutate( enumDecl );
    665968                return handleAggregate( enumDecl );
    666969        }
    667970
    668         Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) {
     971                Declaration *EliminateTypedef::mutate( ContextDecl * contextDecl ) {
    669972                Mutator::mutate( contextDecl );
    670973                return handleAggregate( contextDecl );
    671974        }
    672975
    673         void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
    674                 VerifyCtorDtor verifier;
    675                 acceptAll( translationUnit, verifier );
    676         }
    677 
    678         void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
    679                 FunctionType * funcType = funcDecl->get_functionType();
    680                 std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
    681                 std::list< DeclarationWithType * > &params = funcType->get_parameters();
    682 
    683                 if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
    684                         if ( params.size() == 0 ) {
    685                                 throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
    686                         }
    687                         if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
    688                                 throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
    689                         }
    690                         if ( returnVals.size() != 0 ) {
    691                                 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
    692                         }
    693                 }
    694 
    695                 Visitor::visit( funcDecl );
    696         }
    697 
    698         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
    699                 storageclass = objectDecl->get_storageClass();
    700                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    701                 storageclass = DeclarationNode::NoStorageClass;
    702                 return temp;
    703         }
    704 
    705         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
    706                 // transform [storage_class] ... (struct S){ 3, ... };
    707                 // into [storage_class] struct S temp =  { 3, ... };
    708                 static UniqueName indexName( "_compLit" );
    709 
    710                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageclass, LinkageSpec::C, 0, compLitExpr->get_type(), compLitExpr->get_initializer() );
    711                 compLitExpr->set_type( 0 );
    712                 compLitExpr->set_initializer( 0 );
    713                 delete compLitExpr;
    714                 DeclarationWithType * newtempvar = mutate( tempvar );
    715                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    716                 return new VariableExpr( newtempvar );
    717         }
    718976} // namespace SymTab
    719977
Note: See TracChangeset for help on using the changeset viewer.