Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r46adb83 r6ea87486  
    1010// Created On       : Thu Mar 03 15:45:56 2016
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jun 28 15:30:00 2017
    13 // Update Count     : 61
     12// Last Modified On : Fri Jul 14 16:41:00 2017
     13// Update Count     : 62
    1414//
    1515
     
    1717#include <iterator>
    1818#include "SynTree/Visitor.h"
    19 #include "SynTree/Attribute.h"
    2019#include "SynTree/Type.h"
    2120#include "SynTree/Statement.h"
    2221#include "SynTree/TypeSubstitution.h"
    2322#include "Common/utility.h"
    24 #include "CodeGen/OperatorTable.h"
    2523#include "AddVisit.h"
    2624#include "MakeLibCfa.h"
     
    127125        FunctionType * genDefaultType( Type * paramType ) {
    128126                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    129                 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
     127                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
    130128                ftype->get_parameters().push_back( dstParam );
    131129
     
    178176                        FunctionType * ftype = funcDecl->get_functionType();
    179177                        assert( ! ftype->get_parameters().empty() );
    180                         Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() );
    181                         assert( t );
     178                        Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
    182179                        map.insert( Mangler::mangleType( t ), true );
    183180                }
     
    225222                        FunctionType * ftype = data.genType( refType );
    226223
    227                         if(concurrent_type && CodeGen::isDestructor( data.fname )) {
     224                        if(concurrent_type && InitTweak::isDestructor( data.fname )) {
    228225                                ftype->get_parameters().front()->get_type()->set_mutex( true );
    229226                        }
     
    277274                FunctionType *copyCtorType = genCopyType( refType->clone() );
    278275
    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 
    283276                // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?
    284277                // right now these cases work, but that might change.
     
    304297        /// generates a single struct member operation (constructor call, destructor call, assignment call)
    305298        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
     299                ObjectDecl * returnVal = NULL;
     300                if ( ! func->get_functionType()->get_returnVals().empty() ) {
     301                        returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
     302                }
     303
    306304                InitTweak::InitExpander srcParam( src );
    307305
    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() ) );
     306                // assign to destination (and return value if generic)
     307                UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
     308                Expression *dstselect = new MemberExpr( field, derefExpr );
    310309                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     310
     311                if ( isDynamicLayout && returnVal ) {
     312                        // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?
     313                        Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );
     314                        genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     315                } // if
    311316        }
    312317
     
    396401        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    397402                // Builtins do not use autogeneration.
    398                 if ( aggregateDecl->get_linkage() == LinkageSpec::Builtin ||
     403                if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
    399404                         aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
    400405                        return;
     
    413418
    414419                // field ctors are only generated if default constructor and copy constructor are both generated
    415                 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } );
     420                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
    416421
    417422                if ( functionNesting == 0 ) {
     
    428433                        // generate appropriate calls to member ctor, assignment
    429434                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
    430                         if ( ! CodeGen::isDestructor( dcl->get_name() ) ) {
     435                        if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {
    431436                                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
    432437                        } else {
    433438                                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
    434439                        }
    435                         if ( CodeGen::isAssignment( dcl->get_name() ) ) {
     440                        if ( InitTweak::isAssignment( dcl->get_name() ) ) {
    436441                                // assignment needs to return a value
    437442                                FunctionType * assignType = dcl->get_functionType();
     
    462467                                        // our inheritance model. I think the correct way to handle this is to
    463468                                        // cast the structure to the type of the member and let the resolver
    464                                         // figure out whether it's valid/choose the correct unnamed member
     469                                        // figure out whether it's valid and have a pass afterwards that fixes
     470                                        // the assignment to use pointer arithmetic with the offset of the
     471                                        // member, much like how generic type members are handled.
    465472                                        continue;
    466473                                }
     
    478485        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    479486                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    480                 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
     487                copy->get_args().push_back( new VariableExpr( dstParam ) );
    481488                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    482489                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
     
    490497                ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
    491498                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );
     499                ObjectDecl * returnVal = nullptr;
     500                if ( ! ftype->get_returnVals().empty() ) {
     501                        returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );
     502                }
    492503
    493504                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    494                 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) {
    495                         // also generate return statement in assignment
     505                if ( returnVal ) {
    496506                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    497507                }
     
    502512                // Make function polymorphic in same parameters as generic union, if applicable
    503513                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    504 
     514               
    505515                // default ctor/dtor need only first parameter
    506516                // void ?{}(T *); void ^?{}(T *);
     
    520530                cloneAll( typeParams, copyCtorType->get_forall() );
    521531                cloneAll( typeParams, assignType->get_forall() );
    522 
    523                 // add unused attribute to parameters of default constructor and destructor
    524                 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
    525                 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );
    526532
    527533                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
Note: See TracChangeset for help on using the changeset viewer.