Changeset 620cb95 for src/SymTab


Ignore:
Timestamp:
Mar 3, 2016, 4:50:48 PM (8 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:
972e6f7
Parents:
071a31a
Message:

separate Autogen from Validate, call default ctor/dtors on array elements

Location:
src/SymTab
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/AddVisit.h

    r071a31a r620cb95  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AddVisit.h -- 
     7// AddVisit.h --
    88//
    99// Author           : Richard C. Bilson
     
    8585                maybeAccept( cathStmt->get_decl(), visitor );
    8686        }
     87
     88        template< typename Visitor >
     89        void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     90                std::list< Declaration * >::iterator i = translationUnit.begin();
     91                while ( i != translationUnit.end() ) {
     92                        (*i)->accept( visitor );
     93                        std::list< Declaration * >::iterator next = i;
     94                        next++;
     95                        if ( ! visitor.get_declsToAdd().empty() ) {
     96                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     97                        } // if
     98                        i = next;
     99                } // while
     100        }
    87101} // namespace SymTab
    88102
  • src/SymTab/Validate.cc

    r071a31a r620cb95  
    5454#include "MakeLibCfa.h"
    5555#include "TypeEquality.h"
     56#include "Autogen.h"
    5657#include "ResolvExpr/typeops.h"
    5758
     
    124125
    125126                const Indexer *indexer;
    126         };
    127 
    128         class AutogenerateRoutines : public Visitor {
    129           public:
    130                 /// Generates assignment operators for aggregate types as required
    131                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    132 
    133                 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    134 
    135                 virtual void visit( EnumDecl *enumDecl );
    136                 virtual void visit( StructDecl *structDecl );
    137                 virtual void visit( UnionDecl *structDecl );
    138                 virtual void visit( TypeDecl *typeDecl );
    139                 virtual void visit( ContextDecl *ctxDecl );
    140                 virtual void visit( FunctionDecl *functionDecl );
    141 
    142                 virtual void visit( FunctionType *ftype );
    143                 virtual void visit( PointerType *ftype );
    144 
    145                 virtual void visit( CompoundStmt *compoundStmt );
    146                 virtual void visit( IfStmt *ifStmt );
    147                 virtual void visit( WhileStmt *whileStmt );
    148                 virtual void visit( ForStmt *forStmt );
    149                 virtual void visit( SwitchStmt *switchStmt );
    150                 virtual void visit( ChooseStmt *chooseStmt );
    151                 virtual void visit( CaseStmt *caseStmt );
    152                 virtual void visit( CatchStmt *catchStmt );
    153 
    154                 AutogenerateRoutines() : functionNesting( 0 ) {}
    155           private:
    156                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    157 
    158                 std::list< Declaration * > declsToAdd;
    159                 std::set< std::string > structsDone;
    160                 unsigned int functionNesting;                   // current level of nested functions
    161127        };
    162128
     
    224190                acceptAll( translationUnit, pass2 );
    225191                ReturnChecker::checkFunctionReturns( translationUnit );
    226                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     192                autogenerateRoutines( translationUnit );
    227193                acceptAll( translationUnit, pass3 );
    228194                VerifyCtorDtor::verify( translationUnit );
     
    236202                type->accept( pass2 );
    237203                type->accept( pass3 );
    238         }
    239 
    240         template< typename Visitor >
    241         void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
    242                 std::list< Declaration * >::iterator i = translationUnit.begin();
    243                 while ( i != translationUnit.end() ) {
    244                         (*i)->accept( visitor );
    245                         std::list< Declaration * >::iterator next = i;
    246                         next++;
    247                         if ( ! visitor.get_declsToAdd().empty() ) {
    248                                 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
    249                         } // if
    250                         i = next;
    251                 } // while
    252204        }
    253205
     
    527479        }
    528480
    529         static const std::list< std::string > noLabels;
    530 
    531         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    532                 AutogenerateRoutines visitor;
    533                 acceptAndAdd( translationUnit, visitor, false );
    534         }
    535 
    536         template< typename OutputIterator >
    537         void makeScalarFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    538                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    539                 // unnamed bit fields are not copied as they cannot be accessed
    540                 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    541 
    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 ) );
    545 
    546                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    547                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    548 
    549                 // do something special for unnamed members
    550                 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    551                 fExpr->get_args().push_back( dstselect );
    552 
    553                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    554                 fExpr->get_args().push_back( srcselect );
    555 
    556                 *out++ = new ExprStmt( noLabels, fExpr );
    557         }
    558 
    559         template< typename OutputIterator >
    560         void makeArrayFunction( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, std::string fname, OutputIterator out ) {
    561                 static UniqueName indexName( "_index" );
    562 
    563                 // for a flexible array member nothing is done -- user must define own assignment
    564                 if ( ! array->get_dimension() ) return;
    565 
    566                 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    567                 *out++ = new DeclStmt( noLabels, index );
    568 
    569                 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    570                 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    571                 init->get_args().push_back( new NameExpr( "0" ) );
    572                 Statement *initStmt = new ExprStmt( noLabels, init );
    573                 std::list<Statement *> initList;
    574                 initList.push_back( initStmt );
    575 
    576                 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    577                 cond->get_args().push_back( new VariableExpr( index ) );
    578                 cond->get_args().push_back( array->get_dimension()->clone() );
    579 
    580                 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    581                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    582 
    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 ) );
    586 
    587                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    588                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    589 
    590                 Expression *dstselect = new MemberExpr( member, derefExpr );
    591                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    592                 dstIndex->get_args().push_back( dstselect );
    593                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    594                 fExpr->get_args().push_back( dstIndex );
    595 
    596                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    597                 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    598                 srcIndex->get_args().push_back( srcselect );
    599                 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 ) );
    603         }
    604 
    605         template< typename OutputIterator >
    606         void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
    607                 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    608                 copy->get_args().push_back( new VariableExpr( dstParam ) );
    609                 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    610                 copy->get_args().push_back( new SizeofExpr( unionType ) );
    611 
    612                 *out++ = new ExprStmt( noLabels, copy );
    613         }
    614 
    615         //E ?=?(E volatile*, int),
    616         //  ?=?(E _Atomic volatile*, int);
    617         void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    618                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    619 
    620                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    621                 assignType->get_returnVals().push_back( returnVal );
    622 
    623                 // need two assignment operators with different types
    624                 FunctionType * assignType2 = assignType->clone();
    625 
    626                 // E ?=?(E volatile *, E)
    627                 Type *etype = refType->clone();
    628                 // etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
    629 
    630                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
    631                 assignType->get_parameters().push_back( dstParam );
    632 
    633                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
    634                 assignType->get_parameters().push_back( srcParam );
    635 
    636                 // E ?=?(E volatile *, int)
    637                 assignType2->get_parameters().push_back( dstParam->clone() );
    638                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    639                 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    640                 assignType2->get_parameters().push_back( srcParam2 );
    641 
    642                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    643                 // because each unit generates copies of the default routines for each aggregate.
    644 
    645                 // since there is no definition, these should not be inline
    646                 // make these intrinsic so that the code generator does not make use of them
    647                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
    648                 assignDecl->fixUniqueId();
    649                 FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
    650                 assignDecl2->fixUniqueId();
    651 
    652                 // these should be built in the same way that the prelude
    653                 // functions are, so build a list containing the prototypes
    654                 // and allow MakeLibCfa to autogenerate the bodies.
    655                 std::list< Declaration * > assigns;
    656                 assigns.push_back( assignDecl );
    657                 assigns.push_back( assignDecl2 );
    658 
    659                 LibCfa::makeLibCfa( assigns );
    660 
    661                 // need to remove the prototypes, since this may be nested in a routine
    662                 for (int start = 0, end = assigns.size()/2; start < end; start++) {
    663                         delete assigns.front();
    664                         assigns.pop_front();
    665                 } // for
    666 
    667                 declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
    668         }
    669 
    670         /// Clones a reference type, replacing any parameters it may have with a clone of the provided list
    671         template< typename GenericInstType >
    672         GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
    673                 GenericInstType *clone = refType->clone();
    674                 clone->get_parameters().clear();
    675                 cloneAll( params, clone->get_parameters() );
    676                 return clone;
    677         }
    678 
    679         /// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
    680         TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
    681                 TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
    682 
    683                 if ( src->get_kind() == TypeDecl::Any ) {
    684                         // just include assignment operator assertion
    685                         TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
    686                         FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
    687                         assignFunctionType->get_returnVals().push_back(
    688                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
    689                         assignFunctionType->get_parameters().push_back(
    690                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
    691                         assignFunctionType->get_parameters().push_back(
    692                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
    693                         FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
    694                         dst->get_assertions().push_back( assignAssert );
    695                 }
    696 
    697                 return dst;
    698         }
    699 
    700         void makeStructFunctionBody( StructDecl *aggregateDecl, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
    701                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    702                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    703                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    704                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    705                                 Type * type = dwt->get_type();
    706                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    707                                         type = at->get_base();
    708                                 }
    709 
    710                                 if ( type->get_qualifiers().isConst ) {
    711                                         // don't assign const members
    712                                         continue;
    713                                 }
    714 
    715                                 // temporary hack: for now only works for 2 parameters
    716                                 assert( func->get_functionType()->get_parameters().size() == 2 );
    717 
    718                                 ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
    719                                 ObjectDecl * srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
    720                                 ObjectDecl * returnVal;
    721                                 if ( ! func->get_functionType()->get_returnVals().empty() ) {
    722                                         returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
    723                                 }
    724 
    725                                 if ( isGeneric ) {
    726                                         // rewrite member type in terms of the type variables on this operator
    727                                         DeclarationWithType *fixedMember = dwt->clone();
    728                                         genericSubs.apply( fixedMember );
    729 
    730                                         // assign to both destination and return value
    731                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    732                                                 makeArrayFunction( srcParam, dstParam, fixedMember, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    733                                                 if ( returnVal ) makeArrayFunction( srcParam, returnVal, fixedMember, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    734                                         } else {
    735                                                 makeScalarFunction( srcParam, dstParam, fixedMember, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    736                                                 if ( returnVal ) makeScalarFunction( srcParam, returnVal, fixedMember, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    737                                         } // if
    738                                 } else {
    739                                         // assign to destination
    740                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    741                                                 makeArrayFunction( srcParam, dstParam, dwt, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    742                                         } else {
    743                                                 makeScalarFunction( srcParam, dstParam, dwt, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    744                                         } // if
    745                                 } // if
    746                         } // if
    747                 } // for
    748         } // makeStructFunctionBody
    749 
    750         void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    751                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    752 
    753                 // Make function polymorphic in same parameters as generic struct, if applicable
    754                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    755                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    756                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    757                 TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    758                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    759                         isGeneric = true;
    760                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    761                         assignType->get_forall().push_back( typeParam );
    762                         TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
    763                         genericSubs.add( (*param)->get_name(), newParamType );
    764                         structParams.push_back( new TypeExpr( newParamType ) );
    765                 }
    766 
    767                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    768                 assignType->get_parameters().push_back( dstParam );
    769 
    770                 // void ?{}(T *); void ^?{}(T *);
    771                 FunctionType *ctorType = assignType->clone();
    772                 FunctionType *dtorType = assignType->clone();
    773 
    774                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    775                 assignType->get_parameters().push_back( srcParam );
    776 
    777                 // void ?{}(T *, T);
    778                 FunctionType *copyCtorType = assignType->clone();
    779 
    780                 // T ?=?(T *, T);
    781                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    782                 assignType->get_returnVals().push_back( returnVal );
    783 
    784                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    785                 // because each unit generates copies of the default routines for each aggregate.
    786                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    787                 FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
    788                 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, new CompoundStmt( noLabels ), true, false );
    789                 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
    790                 assignDecl->fixUniqueId();
    791                 ctorDecl->fixUniqueId();
    792                 copyCtorDecl->fixUniqueId();
    793                 dtorDecl->fixUniqueId();
    794 
    795                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    796 
    797                 makeStructFunctionBody( aggregateDecl, assignDecl, genericSubs, isGeneric );
    798                 makeStructFunctionBody( aggregateDecl, copyCtorDecl, genericSubs, isGeneric );
    799 
    800                 declsToAdd.push_back( assignDecl );
    801                 declsToAdd.push_back( ctorDecl );
    802                 declsToAdd.push_back( copyCtorDecl );
    803                 declsToAdd.push_back( dtorDecl );
    804         }
    805 
    806         void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    807                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    808 
    809                 // Make function polymorphic in same parameters as generic union, if applicable
    810                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    811                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    812                 std::list< Expression* > unionParams;  // List of matching parameters to put on types
    813                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    814                         isGeneric = true;
    815                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    816                         assignType->get_forall().push_back( typeParam );
    817                         unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    818                 }
    819 
    820                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    821                 assignType->get_parameters().push_back( dstParam );
    822 
    823                 // default ctor/dtor need only first parameter
    824                 FunctionType * ctorType = assignType->clone();
    825                 FunctionType * dtorType = assignType->clone();
    826 
    827                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    828                 assignType->get_parameters().push_back( srcParam );
    829 
    830                 // copy ctor needs both parameters
    831                 FunctionType * copyCtorType = assignType->clone();
    832 
    833                 // assignment needs both and return value
    834                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    835                 assignType->get_returnVals().push_back( returnVal );
    836 
    837                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    838                 // because each unit generates copies of the default routines for each aggregate.
    839                 FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    840                 FunctionDecl *ctorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
    841                 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );
    842                 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
    843 
    844                 assignDecl->fixUniqueId();
    845                 ctorDecl->fixUniqueId();
    846                 copyCtorDecl->fixUniqueId();
    847                 dtorDecl->fixUniqueId();
    848 
    849                 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    850                 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    851 
    852                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    853 
    854                 // body of assignment and copy ctor is the same
    855                 copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
    856 
    857                 declsToAdd.push_back( assignDecl );
    858                 declsToAdd.push_back( ctorDecl );
    859                 declsToAdd.push_back( copyCtorDecl );
    860                 declsToAdd.push_back( dtorDecl );
    861         }
    862 
    863         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
    864                 if ( ! enumDecl->get_members().empty() ) {
    865                         EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    866                         // enumInst->set_baseEnum( enumDecl );
    867                         // declsToAdd.push_back(
    868                         makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    869                 }
    870         }
    871 
    872         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    873                 if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    874                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    875                         structInst.set_baseStruct( structDecl );
    876                         makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );
    877                         structsDone.insert( structDecl->get_name() );
    878                 } // if
    879         }
    880 
    881         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    882                 if ( ! unionDecl->get_members().empty() ) {
    883                         UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    884                         unionInst.set_baseUnion( unionDecl );
    885                         makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd );
    886                 } // if
    887         }
    888 
    889         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    890                 CompoundStmt *stmts = 0;
    891                 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    892                 typeInst->set_baseType( typeDecl );
    893                 ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
    894                 ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
    895                 if ( typeDecl->get_base() ) {
    896                         stmts = new CompoundStmt( std::list< Label >() );
    897                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    898                         assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    899                         assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    900                         stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
    901                 } // if
    902                 FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    903                 type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
    904                 type->get_parameters().push_back( dst );
    905                 type->get_parameters().push_back( src );
    906                 FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
    907                 declsToAdd.push_back( func );
    908         }
    909 
    910         void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    911                 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    912                         statements.insert( i, new DeclStmt( noLabels, *decl ) );
    913                 } // for
    914                 declsToAdd.clear();
    915         }
    916 
    917         void AutogenerateRoutines::visit( FunctionType *) {
    918                 // ensure that we don't add assignment ops for types defined as part of the function
    919         }
    920 
    921         void AutogenerateRoutines::visit( PointerType *) {
    922                 // ensure that we don't add assignment ops for types defined as part of the pointer
    923         }
    924 
    925         void AutogenerateRoutines::visit( ContextDecl *) {
    926                 // ensure that we don't add assignment ops for types defined as part of the context
    927         }
    928 
    929         template< typename StmtClass >
    930         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
    931                 std::set< std::string > oldStructs = structsDone;
    932                 addVisit( stmt, *this );
    933                 structsDone = oldStructs;
    934         }
    935 
    936         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
    937                 maybeAccept( functionDecl->get_functionType(), *this );
    938                 acceptAll( functionDecl->get_oldDecls(), *this );
    939                 functionNesting += 1;
    940                 maybeAccept( functionDecl->get_statements(), *this );
    941                 functionNesting -= 1;
    942         }
    943 
    944         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
    945                 visitStatement( compoundStmt );
    946         }
    947 
    948         void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
    949                 visitStatement( ifStmt );
    950         }
    951 
    952         void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
    953                 visitStatement( whileStmt );
    954         }
    955 
    956         void AutogenerateRoutines::visit( ForStmt *forStmt ) {
    957                 visitStatement( forStmt );
    958         }
    959 
    960         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    961                 visitStatement( switchStmt );
    962         }
    963 
    964         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
    965                 visitStatement( switchStmt );
    966         }
    967 
    968         void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
    969                 visitStatement( caseStmt );
    970         }
    971 
    972         void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
    973                 visitStatement( cathStmt );
    974         }
    975 
    976481        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    977482                ReturnChecker checker;
  • src/SymTab/module.mk

    r071a31a r620cb95  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    2121       SymTab/FixFunction.cc \
    2222       SymTab/ImplementationType.cc \
    23        SymTab/TypeEquality.cc
     23       SymTab/TypeEquality.cc \
     24       SymTab/Autogen.cc
Note: See TracChangeset for help on using the changeset viewer.