Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    ra9a259c r98735ef  
    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 : Mon Feb 22 12:26:37 2016
    13 // Update Count     : 297
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jan 27 22:03:12 2016
     13// Update Count     : 225
    1414//
    1515
     
    202202        };
    203203
    204         class VerifyCtorDtor : public Visitor {
    205         public:
    206                 /// ensure that constructors and destructors have at least one
    207                 /// parameter, the first of which must be a pointer, and no
    208                 /// return values.
    209                 static void verify( std::list< Declaration * > &translationUnit );
    210 
    211                 // VerifyCtorDtor() {}
    212 
    213                 virtual void visit( FunctionDecl *funcDecl );
    214         private:
    215         };
    216 
    217204        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    218205                Pass1 pass1;
     
    226213                AutogenerateRoutines::autogenerateRoutines( translationUnit );
    227214                acceptAll( translationUnit, pass3 );
    228                 VerifyCtorDtor::verify( translationUnit );
    229215        }
    230216
     
    535521
    536522        template< typename OutputIterator >
    537         void makeScalarFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
     523        void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
    538524                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    539525                // unnamed bit fields are not copied as they cannot be accessed
    540526                if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    541527
    542                 // want to be able to generate assignment, ctor, and dtor generically,
    543                 // so fname is either ?=?, ?{}, or ^?{}
    544                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     528                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    545529
    546530                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    549533                // do something special for unnamed members
    550534                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    551                 fExpr->get_args().push_back( dstselect );
     535                assignExpr->get_args().push_back( dstselect );
    552536
    553537                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    554                 fExpr->get_args().push_back( srcselect );
    555 
    556                 *out++ = new ExprStmt( noLabels, fExpr );
     538                assignExpr->get_args().push_back( srcselect );
     539
     540                *out++ = new ExprStmt( noLabels, assignExpr );
    557541        }
    558542
    559543        template< typename OutputIterator >
    560         void makeArrayFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, std::string fname, OutputIterator out ) {
     544        void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    561545                static UniqueName indexName( "_index" );
    562546
     
    581565                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    582566
    583                 // want to be able to generate assignment, ctor, and dtor generically,
    584                 // so fname is either ?=?, ?{}, or ^?{}
    585                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     567                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    586568
    587569                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     
    592574                dstIndex->get_args().push_back( dstselect );
    593575                dstIndex->get_args().push_back( new VariableExpr( index ) );
    594                 fExpr->get_args().push_back( dstIndex );
     576                assignExpr->get_args().push_back( dstIndex );
    595577
    596578                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     
    598580                srcIndex->get_args().push_back( srcselect );
    599581                srcIndex->get_args().push_back( new VariableExpr( index ) );
    600                 fExpr->get_args().push_back( srcIndex );
    601 
    602                 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) );
     582                assignExpr->get_args().push_back( srcIndex );
     583
     584                *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    603585        }
    604586
     
    750732                                        // assign to both destination and return value
    751733                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    752                                                 makeArrayFunction( srcParam, dstParam, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    753                                                 makeArrayFunction( srcParam, returnVal, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     734                                                makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     735                                                makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    754736                                        } else {
    755                                                 makeScalarFunction( srcParam, dstParam, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
    756                                                 makeScalarFunction( srcParam, returnVal, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     737                                                makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
     738                                                makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    757739                                        } // if
    758740                                } else {
    759741                                        // assign to destination
    760742                                        if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    761                                                 makeArrayFunction( srcParam, dstParam, dwt, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     743                                                makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    762744                                        } else {
    763                                                 makeScalarFunction( srcParam, dstParam, dwt, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );
     745                                                makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    764746                                        } // if
    765747                                } // if
     
    771753        }
    772754
    773         void makeStructCtorDtor( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    774                 FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
    775 
    776                 // Make function polymorphic in same parameters as generic struct, if applicable
    777                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    778                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    779                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    780                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    781                         isGeneric = true;
    782                         TypeDecl *typeParam = (*param)->clone();
    783                         ctorType->get_forall().push_back( typeParam );
    784                         structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    785                 }
    786 
    787                 ObjectDecl *thisParam = new ObjectDecl( "_this", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    788                 ctorType->get_parameters().push_back( thisParam );
    789 
    790                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    791                 // because each unit generates copies of the default routines for each aggregate.
    792                 FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, 0, true, false );
    793                 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
    794                 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false );
    795                 ctorDecl->fixUniqueId();
    796                 copyCtorDecl->fixUniqueId();
    797                 dtorDecl->fixUniqueId();
    798 
    799                 // add definitions
    800                 // TODO: add in calls to default constructors and destructors for fields
    801                 ctorDecl->set_statements( new CompoundStmt( noLabels ) );
    802                 copyCtorDecl->set_statements( new CompoundStmt( noLabels ) );
    803                 dtorDecl->set_statements( new CompoundStmt( noLabels ) );
    804                 declsToAdd.push_back( ctorDecl );
    805                 declsToAdd.push_back( copyCtorDecl );
    806                 declsToAdd.push_back( dtorDecl );
    807 
    808                 ObjectDecl * srcParam = new ObjectDecl( "_other", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    809                 copyCtorDecl->get_functionType()->get_parameters().push_back( srcParam );
    810                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    811                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    812                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    813                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    814                                 Type * type = dwt->get_type();
    815                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    816                                         type = at->get_base();
    817                                 }
    818 
    819                                 if ( type->get_qualifiers().isConst ) {
    820                                         // don't assign const members
    821                                         continue;
    822                                 }
    823 
    824                                 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    825                                         makeArrayFunction( srcParam, thisParam, dwt, array, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    826                                         // if ( isGeneric ) makeArrayFunction( srcParam, returnVal, dwt, array, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    827                                 } else {
    828                                         makeScalarFunction( srcParam, thisParam, dwt, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    829                                         // if ( isGeneric ) makeScalarCtor( srcParam, returnVal, dwt, back_inserter( copyCtorDecl->get_statements()->get_kids() ) );
    830                                 } // if
    831                         } // if
    832                 } // for
    833                 // if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    834         }
    835 
    836         void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
     755        Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    837756                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    838757
     
    848767                }
    849768
     769                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     770                assignType->get_returnVals().push_back( returnVal );
     771
    850772                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    851773                assignType->get_parameters().push_back( dstParam );
    852774
    853                 // default ctor/dtor need only first parameter
    854                 FunctionType * ctorType = assignType->clone();
    855                 FunctionType * dtorType = assignType->clone();
    856 
    857775                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    858776                assignType->get_parameters().push_back( srcParam );
    859 
    860                 // copy ctor needs both parameters
    861                 FunctionType * copyCtorType = assignType->clone();
    862 
    863                 // assignment needs both and return value
    864                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    865                 assignType->get_returnVals().push_back( returnVal );
    866777
    867778                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    868779                // because each unit generates copies of the default routines for each aggregate.
    869780                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    870                 FunctionDecl *ctorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
    871                 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );
    872                 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
    873 
    874781                assignDecl->fixUniqueId();
    875                 ctorDecl->fixUniqueId();
    876                 copyCtorDecl->fixUniqueId();
    877                 dtorDecl->fixUniqueId();
    878782
    879783                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    880784                if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    881 
     785               
    882786                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    883787
    884                 // body of assignment and copy ctor is the same
    885                 copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
    886 
    887                 declsToAdd.push_back( assignDecl );
    888                 declsToAdd.push_back( ctorDecl );
    889                 declsToAdd.push_back( copyCtorDecl );
    890                 declsToAdd.push_back( dtorDecl );
     788                return assignDecl;
    891789        }
    892790
     
    904802                        StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    905803                        structInst.set_baseStruct( structDecl );
    906 
    907804                        declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
    908                         makeStructCtorDtor( structDecl, &structInst, functionNesting, declsToAdd );
    909805                        structsDone.insert( structDecl->get_name() );
    910806                } // if
     
    915811                        UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    916812                        unionInst.set_baseUnion( unionDecl );
    917                         makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd );
     813                        declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
    918814                } // if
    919815        }
     
    11841080        }
    11851081
    1186         void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
    1187                 VerifyCtorDtor verifier;
    1188                 acceptAll( translationUnit, verifier );
    1189         }
    1190 
    1191         void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
    1192                 FunctionType * funcType = funcDecl->get_functionType();
    1193                 std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
    1194                 std::list< DeclarationWithType * > &params = funcType->get_parameters();
    1195 
    1196                 if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
    1197                         if ( params.size() == 0 ) {
    1198                                 throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
    1199                         }
    1200                         if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
    1201                                 throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
    1202                         }
    1203                         if ( returnVals.size() != 0 ) {
    1204                                 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
    1205                         }
    1206                 }
    1207 
    1208                 Visitor::visit( funcDecl );
    1209                 // original idea: modify signature of ctor/dtors and insert appropriate return statements
    1210                 // to cause desired behaviour
    1211                 // new idea: add comma exprs to every ctor call to produce first parameter.
    1212                 // this requires some memoization of the first parameter, because it can be a
    1213                 // complicated expression with side effects (see: malloc). idea: add temporary variable
    1214                 // that is assigned address of constructed object in ctor argument position and
    1215                 // return the temporary. It should also be done after all implicit ctors are
    1216                 // added, so not in this pass!
    1217         }
    12181082} // namespace SymTab
    12191083
Note: See TracChangeset for help on using the changeset viewer.