Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r6ea87486 r46adb83  
    1010// Created On       : Thu Mar 03 15:45:56 2016
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 14 16:41:00 2017
    13 // Update Count     : 62
     12// Last Modified On : Wed Jun 28 15:30:00 2017
     13// Update Count     : 61
    1414//
    1515
     
    1717#include <iterator>
    1818#include "SynTree/Visitor.h"
     19#include "SynTree/Attribute.h"
    1920#include "SynTree/Type.h"
    2021#include "SynTree/Statement.h"
    2122#include "SynTree/TypeSubstitution.h"
    2223#include "Common/utility.h"
     24#include "CodeGen/OperatorTable.h"
    2325#include "AddVisit.h"
    2426#include "MakeLibCfa.h"
     
    125127        FunctionType * genDefaultType( Type * paramType ) {
    126128                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    127                 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
     129                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    128130                ftype->get_parameters().push_back( dstParam );
    129131
     
    176178                        FunctionType * ftype = funcDecl->get_functionType();
    177179                        assert( ! ftype->get_parameters().empty() );
    178                         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 );
    179182                        map.insert( Mangler::mangleType( t ), true );
    180183                }
     
    222225                        FunctionType * ftype = data.genType( refType );
    223226
    224                         if(concurrent_type && InitTweak::isDestructor( data.fname )) {
     227                        if(concurrent_type && CodeGen::isDestructor( data.fname )) {
    225228                                ftype->get_parameters().front()->get_type()->set_mutex( true );
    226229                        }
     
    274277                FunctionType *copyCtorType = genCopyType( refType->clone() );
    275278
     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
    276283                // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?
    277284                // right now these cases work, but that might change.
     
    297304        /// generates a single struct member operation (constructor call, destructor call, assignment call)
    298305        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 
    304306                InitTweak::InitExpander srcParam( src );
    305307
    306                 // assign to destination (and return value if generic)
    307                 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
    308                 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() ) );
    309310                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
    316311        }
    317312
     
    401396        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    402397                // Builtins do not use autogeneration.
    403                 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA ||
     398                if ( aggregateDecl->get_linkage() == LinkageSpec::Builtin ||
    404399                         aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) {
    405400                        return;
     
    418413
    419414                // field ctors are only generated if default constructor and copy constructor are both generated
    420                 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
     415                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } );
    421416
    422417                if ( functionNesting == 0 ) {
     
    433428                        // generate appropriate calls to member ctor, assignment
    434429                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
    435                         if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {
     430                        if ( ! CodeGen::isDestructor( dcl->get_name() ) ) {
    436431                                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
    437432                        } else {
    438433                                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
    439434                        }
    440                         if ( InitTweak::isAssignment( dcl->get_name() ) ) {
     435                        if ( CodeGen::isAssignment( dcl->get_name() ) ) {
    441436                                // assignment needs to return a value
    442437                                FunctionType * assignType = dcl->get_functionType();
     
    467462                                        // our inheritance model. I think the correct way to handle this is to
    468463                                        // cast the structure to the type of the member and let the resolver
    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.
     464                                        // figure out whether it's valid/choose the correct unnamed member
    472465                                        continue;
    473466                                }
     
    485478        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    486479                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    487                 copy->get_args().push_back( new VariableExpr( dstParam ) );
     480                copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
    488481                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    489482                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
     
    497490                ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
    498491                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                 }
    503492
    504493                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    505                 if ( returnVal ) {
     494                if ( CodeGen::isAssignment( funcDecl->get_name() ) ) {
     495                        // also generate return statement in assignment
    506496                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    507497                }
     
    512502                // Make function polymorphic in same parameters as generic union, if applicable
    513503                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    514                
     504
    515505                // default ctor/dtor need only first parameter
    516506                // void ?{}(T *); void ^?{}(T *);
     
    530520                cloneAll( typeParams, copyCtorType->get_forall() );
    531521                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" ) );
    532526
    533527                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
Note: See TracChangeset for help on using the changeset viewer.