Ignore:
Timestamp:
Aug 25, 2017, 10:38:34 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
800d275
Parents:
af08051 (diff), 3eab308c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    raf08051 r28e58fd  
    1313// Update Count     : 62
    1414//
     15
    1516#include "Autogen.h"
    1617
     
    2425#include <vector>                  // for vector
    2526
    26 #include "AddVisit.h"             // for addVisit
    27 #include "Common/ScopedMap.h"     // for ScopedMap
    28 #include "GenPoly/DeclMutator.h"  // for DeclMutator
    29 #include "GenPoly/ScopedSet.h"    // for ScopedSet
    30 #include "Parser/LinkageSpec.h"   // for AutoGen, Intrinsic, Spec
    31 #include "SymTab/Mangler.h"       // for mangleType
    32 #include "SynTree/Statement.h"    // for SwitchStmt (ptr only), CompoundStmt
    33 #include "SynTree/Type.h"         // for Type, ArrayType, Type::StorageClasses
    34 #include "SynTree/Visitor.h"      // for Visitor
     27#include "AddVisit.h"              // for addVisit
     28#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
     29#include "Common/ScopedMap.h"      // for ScopedMap<>::const_iterator, Scope...
     30#include "Common/utility.h"        // for cloneAll, operator+
     31#include "GenPoly/DeclMutator.h"   // for DeclMutator
     32#include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::iterator
     33#include "SymTab/Mangler.h"        // for Mangler
     34#include "SynTree/Attribute.h"     // For Attribute
     35#include "SynTree/Mutator.h"       // for maybeMutate
     36#include "SynTree/Statement.h"     // for CompoundStmt, ReturnStmt, ExprStmt
     37#include "SynTree/Type.h"          // for FunctionType, Type, TypeInstType
     38#include "SynTree/Visitor.h"       // for maybeAccept, Visitor, acceptAll
     39
     40class Attribute;
    3541
    3642namespace SymTab {
     
    130136        FunctionType * genDefaultType( Type * paramType ) {
    131137                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    132                 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
     138                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    133139                ftype->get_parameters().push_back( dstParam );
    134140
     
    150156                ftype->get_returnVals().push_back( returnVal );
    151157                return ftype;
    152         }
    153 
    154         /// true if the aggregate's layout is dynamic
    155         template< typename AggrDecl >
    156         bool hasDynamicLayout( AggrDecl * aggregateDecl ) {
    157                 for ( TypeDecl * param : aggregateDecl->get_parameters() ) {
    158                         if ( param->isComplete() ) return true;
    159                 }
    160                 return false;
    161158        }
    162159
     
    181178                        FunctionType * ftype = funcDecl->get_functionType();
    182179                        assert( ! ftype->get_parameters().empty() );
    183                         Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
     180                        Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() );
     181                        assert( t );
    184182                        map.insert( Mangler::mangleType( t ), true );
    185183                }
     
    227225                        FunctionType * ftype = data.genType( refType );
    228226
    229                         if(concurrent_type && InitTweak::isDestructor( data.fname )) {
     227                        if(concurrent_type && CodeGen::isDestructor( data.fname )) {
    230228                                ftype->get_parameters().front()->get_type()->set_mutex( true );
    231229                        }
     
    279277                FunctionType *copyCtorType = genCopyType( refType->clone() );
    280278
     279                // add unused attribute to parameters of default constructor and destructor
     280                ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
     281                dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
     282
    281283                // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?
    282284                // right now these cases work, but that might change.
     
    301303
    302304        /// generates a single struct member operation (constructor call, destructor call, assignment call)
    303         void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
    304                 ObjectDecl * returnVal = NULL;
    305                 if ( ! func->get_functionType()->get_returnVals().empty() ) {
    306                         returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
    307                 }
    308 
     305        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) {
    309306                InitTweak::InitExpander srcParam( src );
    310307
    311                 // assign to destination (and return value if generic)
    312                 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
    313                 Expression *dstselect = new MemberExpr( field, derefExpr );
     308                // assign to destination
     309                Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), safe_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) );
    314310                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    315 
    316                 if ( isDynamicLayout && returnVal ) {
    317                         // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?
    318                         Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );
    319                         genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    320                 } // if
    321311        }
    322312
    323313        /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies
    324314        template<typename Iterator>
    325         void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
     315        void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) {
    326316                for ( ; member != end; ++member ) {
    327317                        if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
     
    359349
    360350                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    361                                 makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout, forward );
     351                                makeStructMemberOp( dstParam, srcselect, field, func, forward );
    362352                        } // if
    363353                } // for
     
    367357        /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
    368358        template<typename Iterator>
    369         void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, bool isDynamicLayout ) {
     359        void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) {
    370360                FunctionType * ftype = func->get_functionType();
    371361                std::list<DeclarationWithType*> & params = ftype->get_parameters();
     
    393383                                        // matching parameter, initialize field with copy ctor
    394384                                        Expression *srcselect = new VariableExpr(*parameter);
    395                                         makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout );
     385                                        makeStructMemberOp( dstParam, srcselect, field, func );
    396386                                        ++parameter;
    397387                                } else {
    398388                                        // no matching parameter, initialize field with default ctor
    399                                         makeStructMemberOp( dstParam, NULL, field, func, isDynamicLayout );
     389                                        makeStructMemberOp( dstParam, NULL, field, func );
    400390                                }
    401391                        }
     
    413403                // Make function polymorphic in same parameters as generic struct, if applicable
    414404                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    415                 bool isDynamicLayout = hasDynamicLayout( aggregateDecl );  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    416405
    417406                // generate each of the functions based on the supplied FuncData objects
     
    423412
    424413                // field ctors are only generated if default constructor and copy constructor are both generated
    425                 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
     414                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } );
    426415
    427416                if ( functionNesting == 0 ) {
     
    438427                        // generate appropriate calls to member ctor, assignment
    439428                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
    440                         if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {
    441                                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
     429                        if ( ! CodeGen::isDestructor( dcl->get_name() ) ) {
     430                                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl );
    442431                        } else {
    443                                 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
    444                         }
    445                         if ( InitTweak::isAssignment( dcl->get_name() ) ) {
     432                                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false );
     433                        }
     434                        if ( CodeGen::isAssignment( dcl->get_name() ) ) {
    446435                                // assignment needs to return a value
    447436                                FunctionType * assignType = dcl->get_functionType();
     
    472461                                        // our inheritance model. I think the correct way to handle this is to
    473462                                        // cast the structure to the type of the member and let the resolver
    474                                         // figure out whether it's valid and have a pass afterwards that fixes
    475                                         // the assignment to use pointer arithmetic with the offset of the
    476                                         // member, much like how generic type members are handled.
     463                                        // figure out whether it's valid/choose the correct unnamed member
    477464                                        continue;
    478465                                }
    479466                                memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
    480467                                FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
    481                                 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
     468                                makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor );
    482469                                declsToAdd.push_back( ctor );
    483470                        }
     
    490477        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    491478                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    492                 copy->get_args().push_back( new VariableExpr( dstParam ) );
     479                copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
    493480                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    494481                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
     
    502489                ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
    503490                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );
    504                 ObjectDecl * returnVal = nullptr;
    505                 if ( ! ftype->get_returnVals().empty() ) {
    506                         returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );
    507                 }
    508491
    509492                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    510                 if ( returnVal ) {
     493                if ( CodeGen::isAssignment( funcDecl->get_name() ) ) {
     494                        // also generate return statement in assignment
    511495                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    512496                }
     
    535519                cloneAll( typeParams, copyCtorType->get_forall() );
    536520                cloneAll( typeParams, assignType->get_forall() );
     521
     522                // add unused attribute to parameters of default constructor and destructor
     523                ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
     524                dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
    537525
    538526                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
Note: See TracChangeset for help on using the changeset viewer.