Ignore:
Timestamp:
Dec 18, 2015, 2:36:53 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
267cb3d
Parents:
0ddb713
Message:

validate constructors and destructors - ensure they return nothing, have at least one parameter, and take a pointer as the first parameter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r0ddb713 r9cb8e88d  
    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
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Nov 20 16:33:52 2015
    13 // Update Count     : 201
     12// Last Modified On : Fri Dec 18 14:32:59 2015
     13// Update Count     : 268
    1414//
    1515
     
    6363                /// Flattens nested struct types
    6464                static void hoistStruct( std::list< Declaration * > &translationUnit );
    65  
     65
    6666                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    67  
     67
    6868                virtual void visit( StructDecl *aggregateDecl );
    6969                virtual void visit( UnionDecl *aggregateDecl );
     
    107107
    108108                const Indexer *indexer;
    109  
     109
    110110                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    111111                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     
    132132
    133133                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    134  
     134
    135135                virtual void visit( EnumDecl *enumDecl );
    136136                virtual void visit( StructDecl *structDecl );
     
    142142                virtual void visit( FunctionType *ftype );
    143143                virtual void visit( PointerType *ftype );
    144  
     144
    145145                virtual void visit( CompoundStmt *compoundStmt );
    146146                virtual void visit( IfStmt *ifStmt );
     
    155155          private:
    156156                template< typename StmtClass > void visitStatement( StmtClass *stmt );
    157  
     157
    158158                std::list< Declaration * > declsToAdd;
    159159                std::set< std::string > structsDone;
     
    188188        };
    189189
     190        class VerifyCtorDtor : public Visitor {
     191        public:
     192                /// ensure that constructors and destructors have at least one
     193                /// parameter, the first of which must be a pointer, and no
     194                /// return values.
     195                static void verify( std::list< Declaration * > &translationUnit );
     196
     197                // VerifyCtorDtor() {}
     198
     199                virtual void visit( FunctionDecl *funcDecl );
     200        private:
     201        };
     202
    190203        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    191204                Pass1 pass1;
     
    198211                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    199212                acceptAll( translationUnit, pass3 );
    200         }
    201        
     213                VerifyCtorDtor::verify( translationUnit );
     214        }
     215
    202216        void validateType( Type *type, const Indexer *indexer ) {
    203217                Pass1 pass1;
     
    307321        void Pass1::visit( EnumDecl *enumDecl ) {
    308322                // Set the type of each member of the enumeration to be EnumConstant
    309  
     323
    310324                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    311325                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
     
    331345                                ++i;
    332346                                func->get_parameters().erase( j );
    333                                 if ( i != end ) { 
     347                                if ( i != end ) {
    334348                                        throw SemanticError( "invalid type void in function type ", func );
    335349                                } // if
     
    512526
    513527                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    514  
     528
    515529                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    516530                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    517  
     531
    518532                // do something special for unnamed members
    519533                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    520534                assignExpr->get_args().push_back( dstselect );
    521  
     535
    522536                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    523537                assignExpr->get_args().push_back( srcselect );
    524  
     538
    525539                *out++ = new ExprStmt( noLabels, assignExpr );
    526540        }
     
    529543        void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    530544                static UniqueName indexName( "_index" );
    531  
     545
    532546                // for a flexible array member nothing is done -- user must define own assignment
    533547                if ( ! array->get_dimension() ) return;
    534  
     548
    535549                ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    536550                *out++ = new DeclStmt( noLabels, index );
    537  
     551
    538552                UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    539553                init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     
    542556                std::list<Statement *> initList;
    543557                initList.push_back( initStmt );
    544  
     558
    545559                UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    546560                cond->get_args().push_back( new VariableExpr( index ) );
    547561                cond->get_args().push_back( array->get_dimension()->clone() );
    548  
     562
    549563                UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    550564                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    551  
     565
    552566                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    553  
     567
    554568                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    555569                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    556  
     570
    557571                Expression *dstselect = new MemberExpr( member, derefExpr );
    558572                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
     
    560574                dstIndex->get_args().push_back( new VariableExpr( index ) );
    561575                assignExpr->get_args().push_back( dstIndex );
    562  
     576
    563577                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    564578                UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     
    566580                srcIndex->get_args().push_back( new VariableExpr( index ) );
    567581                assignExpr->get_args().push_back( srcIndex );
    568  
     582
    569583                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    570584        }
    571585
    572         //E ?=?(E volatile*, int), 
     586        //E ?=?(E volatile*, int),
    573587        //  ?=?(E _Atomic volatile*, int);
    574588        void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    575589                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    576  
     590
    577591                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    578592                assignType->get_returnVals().push_back( returnVal );
     
    593607                // E ?=?(E volatile *, int)
    594608                assignType2->get_parameters().push_back( dstParam->clone() );
    595                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 
     609                BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    596610                ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    597611                assignType2->get_parameters().push_back( srcParam2 );
     
    645659                        structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    646660                }
    647  
     661
    648662                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    649663                assignType->get_returnVals().push_back( returnVal );
    650  
     664
    651665                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    652666                assignType->get_parameters().push_back( dstParam );
    653  
     667
    654668                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    655669                assignType->get_parameters().push_back( srcParam );
     
    659673                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    660674                assignDecl->fixUniqueId();
    661  
     675
    662676                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    663677                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    664                                 // query the type qualifiers of this field and skip assigning it if it is marked const. 
     678                                // query the type qualifiers of this field and skip assigning it if it is marked const.
    665679                                // If it is an array type, we need to strip off the array layers to find its qualifiers.
    666680                                Type * type = dwt->get_type();
     
    682696                } // for
    683697                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    684  
     698
    685699                return assignDecl;
    686700        }
     
    697711                        unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    698712                }
    699  
     713
    700714                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    701715                assignType->get_returnVals().push_back( returnVal );
    702  
     716
    703717                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    704718                assignType->get_parameters().push_back( dstParam );
    705  
     719
    706720                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    707721                assignType->get_parameters().push_back( srcParam );
    708  
     722
    709723                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    710724                // because each unit generates copies of the default routines for each aggregate.
    711725                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    712726                assignDecl->fixUniqueId();
    713  
     727
    714728                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    715729                copy->get_args().push_back( new VariableExpr( dstParam ) );
     
    719733                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
    720734                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    721  
     735
    722736                return assignDecl;
    723737        }
     
    727741                        EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    728742                        // enumInst->set_baseEnum( enumDecl );
    729                         // declsToAdd.push_back( 
     743                        // declsToAdd.push_back(
    730744                        makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    731745                }
     
    847861
    848862        Type *EliminateTypedef::mutate( TypeInstType * typeInst ) {
    849                 // instances of typedef types will come here. If it is an instance 
     863                // instances of typedef types will come here. If it is an instance
    850864                // of a typdef type, link the instance to its actual type.
    851865                TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     
    871885                Declaration *ret = Mutator::mutate( tyDecl );
    872886                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    873                         // typedef to the same name from the same scope 
     887                        // typedef to the same name from the same scope
    874888                        // must be from the same type
    875889
     
    9931007        }
    9941008
     1009        void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
     1010                VerifyCtorDtor verifier;
     1011                acceptAll( translationUnit, verifier );
     1012        }
     1013
     1014        void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
     1015                FunctionType * funcType = funcDecl->get_functionType();
     1016                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     1017                std::list< DeclarationWithType * > &params = funcType->get_parameters();
     1018
     1019                if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
     1020                        if ( params.size() == 0 ) {
     1021                                throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
     1022                        }
     1023                        if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
     1024                                throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
     1025                        }
     1026                        if ( returnVals.size() != 0 ) {
     1027                                throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     1028                        }
     1029                }
     1030
     1031                Visitor::visit( funcDecl );
     1032                // original idea: modify signature of ctor/dtors and insert appropriate return statements
     1033                // to cause desired behaviour
     1034                // new idea: add comma exprs to every ctor call to produce first parameter.
     1035                // this requires some memoization of the first parameter, because it can be a
     1036                // complicated expression with side effects (see: malloc). idea: add temporary variable
     1037                // that is assigned address of constructed object in ctor argument position and
     1038                // return the temporary. It should also be done after all implicit ctors are
     1039                // added, so not in this pass!
     1040        }
    9951041} // namespace SymTab
    9961042
Note: See TracChangeset for help on using the changeset viewer.