Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r679864e1 r40e636a  
    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 : Rob Schluntz
    12 // Last Modified On : Tue Oct 06 15:40:35 2015
    13 // Update Count     : 219
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 12 17:49:21 2016
     13// Update Count     : 298
    1414//
    1515
     
    4040#include <list>
    4141#include <iterator>
     42#include "Common/utility.h"
     43#include "Common/UniqueName.h"
    4244#include "Validate.h"
    4345#include "SynTree/Visitor.h"
    4446#include "SynTree/Mutator.h"
    4547#include "SynTree/Type.h"
     48#include "SynTree/Expression.h"
    4649#include "SynTree/Statement.h"
    4750#include "SynTree/TypeSubstitution.h"
     
    4952#include "FixFunction.h"
    5053// #include "ImplementationType.h"
    51 #include "utility.h"
    52 #include "UniqueName.h"
     54#include "GenPoly/DeclMutator.h"
    5355#include "AddVisit.h"
    5456#include "MakeLibCfa.h"
    5557#include "TypeEquality.h"
     58#include "Autogen.h"
     59#include "ResolvExpr/typeops.h"
    5660
    5761#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    6266                /// Flattens nested struct types
    6367                static void hoistStruct( std::list< Declaration * > &translationUnit );
    64  
     68
    6569                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    66  
     70
    6771                virtual void visit( StructDecl *aggregateDecl );
    6872                virtual void visit( UnionDecl *aggregateDecl );
    6973
    7074                virtual void visit( CompoundStmt *compoundStmt );
    71                 virtual void visit( IfStmt *ifStmt );
    72                 virtual void visit( WhileStmt *whileStmt );
    73                 virtual void visit( ForStmt *forStmt );
    7475                virtual void visit( SwitchStmt *switchStmt );
    75                 virtual void visit( ChooseStmt *chooseStmt );
    76                 virtual void visit( CaseStmt *caseStmt );
    77                 virtual void visit( CatchStmt *catchStmt );
    7876          private:
    7977                HoistStruct();
     
    8583        };
    8684
    87         /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers
     85        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    8886        class Pass1 : public Visitor {
    8987                typedef Visitor Parent;
     
    10098                virtual void visit( StructInstType *structInst );
    10199                virtual void visit( UnionInstType *unionInst );
    102                 virtual void visit( ContextInstType *contextInst );
     100                virtual void visit( TraitInstType *contextInst );
    103101                virtual void visit( StructDecl *structDecl );
    104102                virtual void visit( UnionDecl *unionDecl );
     
    106104
    107105                const Indexer *indexer;
    108  
     106
    109107                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    110108                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     
    125123        };
    126124
    127         class AddStructAssignment : public Visitor {
     125        class ReturnChecker : public Visitor {
    128126          public:
    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 ) {}
     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 );
    154130          private:
    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
     131                virtual void visit( FunctionDecl * functionDecl );
     132
     133                virtual void visit( ReturnStmt * returnStmt );
     134
     135                std::list< DeclarationWithType * > returnVals;
    160136        };
    161137
    162138        class EliminateTypedef : public Mutator {
    163139          public:
    164           EliminateTypedef() : scopeLevel( 0 ) {}
    165             /// Replaces typedefs by forward declarations
     140                EliminateTypedef() : scopeLevel( 0 ) {}
     141                /// Replaces typedefs by forward declarations
    166142                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    167143          private:
     
    177153                virtual Declaration *mutate( UnionDecl * unionDecl );
    178154                virtual Declaration *mutate( EnumDecl * enumDecl );
    179                 virtual Declaration *mutate( ContextDecl * contextDecl );
     155                virtual Declaration *mutate( TraitDecl * contextDecl );
    180156
    181157                template<typename AggDecl>
    182158                AggDecl *handleAggregate( AggDecl * aggDecl );
    183159
     160                template<typename AggDecl>
     161                void addImplicitTypedef( AggDecl * aggDecl );
     162
    184163                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
    185                 typedef std::map< std::string, TypeDecl * > TypeDeclMap;
    186164                TypedefMap typedefNames;
    187                 TypeDeclMap typedeclNames;
    188165                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 );
    189183        };
    190184
     
    193187                Pass2 pass2( doDebug, 0 );
    194188                Pass3 pass3( 0 );
     189                CompoundLiteral compoundliteral;
     190
    195191                EliminateTypedef::eliminateTypedef( translationUnit );
    196192                HoistStruct::hoistStruct( translationUnit );
     193                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1
    197194                acceptAll( translationUnit, pass1 );
    198195                acceptAll( translationUnit, pass2 );
    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 );
     196                ReturnChecker::checkFunctionReturns( translationUnit );
     197                compoundliteral.mutateDeclarationList( translationUnit );
    202198                acceptAll( translationUnit, pass3 );
    203         }
    204        
     199                VerifyCtorDtor::verify( translationUnit );
     200        }
     201
    205202        void validateType( Type *type, const Indexer *indexer ) {
    206203                Pass1 pass1;
     
    210207                type->accept( pass2 );
    211208                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
    226209        }
    227210
     
    280263        }
    281264
    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 
    294265        void HoistStruct::visit( SwitchStmt *switchStmt ) {
    295266                addVisit( switchStmt, *this );
    296267        }
    297268
    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 
    310269        void Pass1::visit( EnumDecl *enumDecl ) {
    311270                // Set the type of each member of the enumeration to be EnumConstant
    312  
    313271                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    314272                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    315273                        assert( obj );
    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 ) ;
     274                        obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
    319275                } // for
    320276                Parent::visit( enumDecl );
     
    322278
    323279        namespace {
    324                 template< typename DWTIterator >
    325                 void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
     280                template< typename DWTList >
     281                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    326282                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    327283                        // entirely other fix ups are handled by the FixFunction class
     284                        typedef typename DWTList::iterator DWTIterator;
     285                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
    328286                        if ( begin == end ) return;
    329287                        FixFunction fixer;
    330288                        DWTIterator i = begin;
    331                         *i = (*i )->acceptMutator( fixer );
     289                        *i = (*i)->acceptMutator( fixer );
    332290                        if ( fixer.get_isVoid() ) {
    333291                                DWTIterator j = i;
    334292                                ++i;
    335                                 func->get_parameters().erase( j );
    336                                 if ( i != end ) { 
     293                                dwts.erase( j );
     294                                if ( i != end ) {
    337295                                        throw SemanticError( "invalid type void in function type ", func );
    338296                                } // if
     
    352310        void Pass1::visit( FunctionType *func ) {
    353311                // Fix up parameters and return types
    354                 fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
    355                 fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
     312                fixFunctionList( func->get_parameters(), func );
     313                fixFunctionList( func->get_returnVals(), func );
    356314                Visitor::visit( func );
    357315        }
     
    370328                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    371329                if ( st ) {
    372                         assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
     330                        //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
    373331                        structInst->set_baseStruct( st );
    374332                } // if
     
    392350        }
    393351
    394         void Pass2::visit( ContextInstType *contextInst ) {
     352        void Pass2::visit( TraitInstType *contextInst ) {
    395353                Parent::visit( contextInst );
    396                 ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
     354                TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
    397355                if ( ! ctx ) {
    398356                        throw SemanticError( "use of undeclared context " + contextInst->get_name() );
     
    400358                for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    401359                        for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    402                                 if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
     360                                if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
    403361                                        cloneAll( otherCtx->get_members(), contextInst->get_members() );
    404362                                } else {
     
    416374
    417375        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 );
    418378                if ( ! structDecl->get_members().empty() ) {
    419379                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     
    425385                        } // if
    426386                } // if
    427                 Indexer::visit( structDecl );
    428387        }
    429388
    430389        void Pass2::visit( UnionDecl *unionDecl ) {
     390                Parent::visit( unionDecl );
    431391                if ( ! unionDecl->get_members().empty() ) {
    432392                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     
    438398                        } // if
    439399                } // if
    440                 Indexer::visit( unionDecl );
    441400        }
    442401
     
    464423                        while ( ! toBeDone.empty() ) {
    465424                                for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    466                                         if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
     425                                        if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
    467426                                                for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    468427                                                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
     
    501460        }
    502461
    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 );
     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 );
    708481                }
    709482        }
    710483
    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         }
    814484
    815485        bool isTypedef( Declaration *decl ) {
     
    820490                EliminateTypedef eliminator;
    821491                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                }
    822500                filter( translationUnit, isTypedef, true );
     501
    823502        }
    824503
    825504        Type *EliminateTypedef::mutate( TypeInstType * typeInst ) {
    826                 // instances of typedef types will come here. If it is an instance 
     505                // instances of typedef types will come here. If it is an instance
    827506                // of a typdef type, link the instance to its actual type.
    828507                TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     
    837516                                }
    838517                                rtt->get_parameters().clear();
    839                                 cloneAll(typeInst->get_parameters(), rtt->get_parameters());
     518                                cloneAll( typeInst->get_parameters(), rtt->get_parameters() );
     519                                mutateAll( rtt->get_parameters(), *this );  // recursively fix typedefs on parameters
    840520                        } // if
    841521                        delete typeInst;
    842522                        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() );
    847523                } // if
    848524                return typeInst;
     
    851527        Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    852528                Declaration *ret = Mutator::mutate( tyDecl );
     529
    853530                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    854                         // typedef to the same name from the same scope 
     531                        // typedef to the same name from the same scope
    855532                        // must be from the same type
    856533
    857534                        Type * t1 = tyDecl->get_base();
    858535                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    859                         if ( ! typeEquals( t1, t2, true ) ) {
     536                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    860537                                throw SemanticError( "cannot redefine typedef: " + tyDecl->get_name() );
    861538                        }
     
    876553                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
    877554                        return new UnionDecl( aggDecl->get_name() );
     555                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( tyDecl->get_base() ) ) {
     556                        return new EnumDecl( enumDecl->get_name() );
    878557                } else {
    879558                        return ret;
     
    886565                        typedefNames.erase( i ) ;
    887566                } // if
    888 
    889                 typedeclNames[ typeDecl->get_name() ] = typeDecl;
    890567                return typeDecl;
    891568        }
     
    902579                DeclarationWithType *ret = Mutator::mutate( objDecl );
    903580                typedefNames = oldNames;
     581                // is the type a function?
    904582                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) {
     583                        // replace the current object declaration with a function declaration
    905584                        return new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn() );
    906585                } else if ( objDecl->get_isInline() || objDecl->get_isNoreturn() ) {
     
    937616        }
    938617
    939         // there may be typedefs nested within aggregates
    940         // in order for everything to work properly, these
    941         // should be removed as well
     618        // there may be typedefs nested within aggregates in order for everything to work properly, these should be removed
     619        // as well
    942620        template<typename AggDecl>
    943621        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
     
    954632        }
    955633
     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
    956650        Declaration *EliminateTypedef::mutate( StructDecl * structDecl ) {
     651                addImplicitTypedef( structDecl );
    957652                Mutator::mutate( structDecl );
    958653                return handleAggregate( structDecl );
     
    960655
    961656        Declaration *EliminateTypedef::mutate( UnionDecl * unionDecl ) {
     657                addImplicitTypedef( unionDecl );
    962658                Mutator::mutate( unionDecl );
    963659                return handleAggregate( unionDecl );
     
    965661
    966662        Declaration *EliminateTypedef::mutate( EnumDecl * enumDecl ) {
     663                addImplicitTypedef( enumDecl );
    967664                Mutator::mutate( enumDecl );
    968665                return handleAggregate( enumDecl );
    969666        }
    970667
    971                 Declaration *EliminateTypedef::mutate( ContextDecl * contextDecl ) {
     668        Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) {
    972669                Mutator::mutate( contextDecl );
    973670                return handleAggregate( contextDecl );
    974671        }
    975672
     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        }
    976718} // namespace SymTab
    977719
Note: See TracChangeset for help on using the changeset viewer.