Changes in / [afab6dc:38bfe32a]


Ignore:
Location:
src
Files:
2 added
32 edited

Legend:

Unmodified
Added
Removed
  • src/ArgTweak/FunctionFixer.cc

    rafab6dc r38bfe32a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FunctionFixer.cc -- 
     7// FunctionFixer.cc --
    88//
    99// Author           : Rodolfo G. Esteves
     
    4242        Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) throw ( SemanticError ) {
    4343                assert( untypedExpr != 0 );
    44                 NameExpr *function;
    4544
    46                 if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) {
     45                if ( NameExpr * function = dynamic_cast< NameExpr *>(untypedExpr->get_function() ) ) {
    4746                        std::list < DeclarationWithType * > options;
    4847                        index->lookupId ( function->get_name(), options );
    4948                        for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) {
    50                                 FunctionType *f;
    51                                 if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 ) {
     49                                if ( FunctionType * f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) )   {
    5250                                        std::list < DeclarationWithType * > &pars = f->get_parameters();
    53 
    5451                                        bool candidateExists ;
    55                                         for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
     52                                        for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ ) {
    5653                                                if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
    57 
     54                                        }
    5855                                        if ( ! candidateExists ) throw SemanticError("Error in function call");
    5956                                } // if
  • src/CodeGen/CodeGenerator.cc

    rafab6dc r38bfe32a  
    2626#include "SynTree/Statement.h"
    2727#include "SynTree/Type.h"
     28#include "SynTree/Attribute.h"
    2829
    2930#include "Common/utility.h"
     
    3334#include "OperatorTable.h"
    3435#include "GenType.h"
     36
     37#include "InitTweak/InitTweak.h"
    3538
    3639using namespace std;
     
    7477        }
    7578
     79        void CodeGenerator::genAttributes( std::list< Attribute * > & attributes ) {
     80                if ( ! attributes.empty() ) {
     81                        output << "__attribute__ ((";
     82                        for ( Attribute *& attr : attributes ) {
     83                                if ( ! attr->empty() ) {
     84                                        output << attr->get_name() << "(";
     85                                        genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() );
     86                                        output << ")";
     87                                }
     88                                output << ",";
     89                        }
     90                        output << ")) ";
     91                }
     92        }
     93
     94
    7695        //*** Declarations
    7796        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
    78                 // generalize this
    79                 FunctionDecl::Attribute attr = functionDecl->get_attribute();
    80                 switch ( attr.type ) {
    81                         case FunctionDecl::Attribute::Constructor:
    82                                 output << "__attribute__ ((constructor";
    83                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    84                                         output << "(" << attr.priority << ")";
    85                                 }
    86                                 output << ")) ";
    87                                 break;
    88                         case FunctionDecl::Attribute::Destructor:
    89                                 output << "__attribute__ ((destructor";
    90                                 if ( attr.priority != FunctionDecl::Attribute::Default ) {
    91                                         output << "(" << attr.priority << ")";
    92                                 }
    93                                 output << ")) ";
    94                                 break;
    95                         default:
    96                                 break;
    97                 }
     97                genAttributes( functionDecl->get_attributes() );
     98
    9899                handleStorageClass( functionDecl );
    99100                if ( functionDecl->get_isInline() ) {
     
    269270                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    270271                                                        newExpr->get_args().push_back( *arg );
     272                                                        assert( (*arg)->get_results().size() == 1 );
     273                                                        Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );
     274                                                        assert( type );
     275                                                        newExpr->get_results().push_back( type );
    271276                                                        *arg = newExpr;
    272277                                                } // if
     
    297302                                        if ( applicationExpr->get_args().size() == 1 ) {
    298303                                                // the expression fed into a single parameter constructor or destructor
    299                                                 // may contain side effects - output as a void expression
    300                                                 output << "((void)(";
     304                                                // may contain side effects, so must still output this expression
     305                                                output << "(";
    301306                                                (*arg++)->accept( *this );
    302                                                 output << ")) /* " << opInfo.inputName << " */";
     307                                                output << ") /* " << opInfo.inputName << " */";
    303308                                        } else if ( applicationExpr->get_args().size() == 2 ) {
    304309                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    382387                                        if ( untypedExpr->get_args().size() == 1 ) {
    383388                                                // the expression fed into a single parameter constructor or destructor
    384                                                 // may contain side effects - output as a void expression
    385                                                 output << "((void)(";
     389                                                // may contain side effects, so must still output this expression
     390                                                output << "(";
    386391                                                (*arg++)->accept( *this );
    387                                                 output << ")) /* " << opInfo.inputName << " */";
     392                                                output << ") /* " << opInfo.inputName << " */";
    388393                                        } else if ( untypedExpr->get_args().size() == 2 ) {
    389394                                                // intrinsic two parameter constructors are essentially bitwise assignment
     
    611616
    612617        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    613                 // I don't see why this check is necessary.
    614                 // If this starts to cause problems then put it back in,
    615                 // with an explanation
    616618                assert( exprStmt );
    617 
    618                 // if ( exprStmt != 0 ) {
    619                 exprStmt->get_expr()->accept( *this );
    620                 output << ";" ;
    621                 // } // if
     619                // cast the top-level expression to void to reduce gcc warnings.
     620                Expression * expr = new CastExpr( exprStmt->get_expr() );
     621                expr->accept( *this );
     622                output << ";";
    622623        }
    623624
     
    728729
    729730        void CodeGenerator::visit( WhileStmt *whileStmt ) {
    730                 if ( whileStmt->get_isDoWhile() )
     731                if ( whileStmt->get_isDoWhile() ) {
    731732                        output << "do" ;
    732                 else {
     733                } else {
    733734                        output << "while (" ;
    734735                        whileStmt->get_condition()->accept( *this );
     
    754755                output << "for (;";
    755756
    756                 if ( forStmt->get_condition() != 0 )
     757                if ( forStmt->get_condition() != 0 ) {
    757758                        forStmt->get_condition()->accept( *this );
     759                }
    758760                output << ";";
    759761
    760                 if ( forStmt->get_increment() != 0 )
    761                         forStmt->get_increment()->accept( *this );
     762                if ( forStmt->get_increment() != 0 ) {
     763                        // cast the top-level expression to void to reduce gcc warnings.
     764                        Expression * expr = new CastExpr( forStmt->get_increment() );
     765                        expr->accept( *this );
     766                }
    762767                output << ") ";
    763768
  • src/CodeGen/CodeGenerator.h

    rafab6dc r38bfe32a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.h -- 
     7// CodeGenerator.h --
    88//
    99// Author           : Richard C. Bilson
     
    6060                virtual void visit( MemberExpr *memberExpr );
    6161                virtual void visit( VariableExpr *variableExpr );
    62                 virtual void visit( ConstantExpr *constantExpr ); 
     62                virtual void visit( ConstantExpr *constantExpr );
    6363                virtual void visit( SizeofExpr *sizeofExpr );
    6464                virtual void visit( AlignofExpr *alignofExpr );
     
    8585                virtual void visit( ForStmt * );
    8686                virtual void visit( NullStmt * );
    87                 virtual void visit( DeclStmt * );
     87                virtual void visit( DeclStmt * );
     88
     89                void genAttributes( std::list< Attribute * > & attributes );
    8890
    8991                template< class Iterator > void genCommaList( Iterator begin, Iterator end );
     
    108110
    109111        };
    110        
     112
    111113        template< class Iterator >
    112114        void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
     
    119121                } // for
    120122        }
    121  
     123
    122124        inline bool doSemicolon( Declaration* decl ) {
    123125                if ( FunctionDecl* func = dynamic_cast< FunctionDecl* >( decl ) ) {
  • src/GenPoly/Box.cc

    rafab6dc r38bfe32a  
    19471947                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    19481948                                derefExpr->get_args().push_back( derefdVar );
     1949                                // xxx - should set results on derefExpr
    19491950                                derefdVar = derefExpr;
    19501951                        }
  • src/GenPoly/Specialize.cc

    rafab6dc r38bfe32a  
    2525#include "SynTree/Statement.h"
    2626#include "SynTree/Type.h"
     27#include "SynTree/Attribute.h"
    2728#include "SynTree/TypeSubstitution.h"
    2829#include "SynTree/Mutator.h"
     
    101102                thunkFunc->fixUniqueId();
    102103
     104                // thunks may be generated and not used - silence warning with attribute
     105                thunkFunc->get_attributes().push_back( new Attribute( "unused" ) );
     106
    103107                // thread thunk parameters into call to actual function, naming thunk parameters as we go
    104108                UniqueName paramNamer( paramPrefix );
  • src/InitTweak/FixGlobalInit.cc

    rafab6dc r38bfe32a  
    2222#include "SynTree/Initializer.h"
    2323#include "SynTree/Visitor.h"
     24#include "SynTree/Attribute.h"
    2425#include <algorithm>
    2526
     
    116117        GlobalFixer::GlobalFixer( const std::string & name, bool inLibrary ) : tempNamer( "_global_init" ) {
    117118                std::string fixedName = globalFunctionName( name );
    118                 initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Constructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) );
    119 
    120                 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Destructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) );
     119                std::list< Expression * > ctorParameters;
     120                std::list< Expression * > dtorParameters;
     121                if ( inLibrary ) {
     122                        // Constructor/destructor attributes take a single parameter which
     123                        // is the priority, with lower numbers meaning higher priority.
     124                        // Functions specified with priority are guaranteed to run before
     125                        // functions without a priority. To ensure that constructors and destructors
     126                        // for library code are run before constructors and destructors for user code,
     127                        // specify a priority when building the library. Priorities 0-100 are reserved by gcc.
     128                        ctorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
     129                        dtorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
     130                }
     131                initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     132                initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) );
     133                destroyFunction = new FunctionDecl( "_destroy_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     134                destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) );
    121135        }
    122136
     
    125139                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    126140
    127                 // if ( objDecl->get_init() == NULL ) return;
    128141                if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
    129                 if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
    130142                if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    131143                // C allows you to initialize objects with constant expressions
     
    146158                        init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    147159                        init->get_args().push_back( new VariableExpr( newObj ) );
    148                         initStatements.push_back( new ExprStmt( noLabels, init ) );
     160                        initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
    149161
    150162                        // add destructor calls to global destroy function
    151163                        UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
    152164                        destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    153                         destroyStatements.push_front( new ExprStmt( noLabels, destroy ) );
     165                        destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
    154166                }
    155167        }
  • src/InitTweak/FixInit.cc

    rafab6dc r38bfe32a  
    132132                                return appExpr;
    133133                        } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    134                                 // FunctionType * ftype = funcDecl->get_functionType();
    135134                                FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    136135                                assert( ftype );
  • src/InitTweak/GenInit.cc

    rafab6dc r38bfe32a  
    164164                                                assert( ctor.size() == 1 );
    165165                                                assert( dtor.size() == 1 );
    166 
    167                                                 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     166                                                objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctor.front() ), new ImplicitCtorDtorStmt( dtor.front() ), objDecl->get_init() ) );
    168167                                        } else {
    169168                                                // array came with an initializer list: initialize each element
     
    185184                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
    186185                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
    187                                         objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
     186                                        objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
    188187                                }
    189188                        }
  • src/InitTweak/InitTweak.cc

    rafab6dc r38bfe32a  
    77
    88namespace InitTweak {
    9   namespace {
    10     class HasDesignations : public Visitor {
    11     public:
    12       bool hasDesignations = false;
    13       template<typename Init>
    14       void handleInit( Init * init ) {
    15         if ( ! init->get_designators().empty() ) hasDesignations = true;
    16         else Visitor::visit( init );
    17       }
    18       virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
    19       virtual void visit( ListInit * listInit ) { handleInit( listInit); }
    20     };
     9        namespace {
     10                class HasDesignations : public Visitor {
     11                public:
     12                        bool hasDesignations = false;
     13                        template<typename Init>
     14                        void handleInit( Init * init ) {
     15                                if ( ! init->get_designators().empty() ) hasDesignations = true;
     16                                else Visitor::visit( init );
     17                        }
     18                        virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
     19                        virtual void visit( ListInit * listInit ) { handleInit( listInit); }
     20                };
    2121
    22     class InitExpander : public Visitor {
    23       public:
    24       InitExpander() {}
    25       virtual void visit( SingleInit * singleInit );
    26       virtual void visit( ListInit * listInit );
    27       std::list< Expression * > argList;
    28     };
     22                class InitExpander : public Visitor {
     23                        public:
     24                        InitExpander() {}
     25                        virtual void visit( SingleInit * singleInit );
     26                        virtual void visit( ListInit * listInit );
     27                        std::list< Expression * > argList;
     28                };
    2929
    30     void InitExpander::visit( SingleInit * singleInit ) {
    31       argList.push_back( singleInit->get_value()->clone() );
    32     }
     30                void InitExpander::visit( SingleInit * singleInit ) {
     31                        argList.push_back( singleInit->get_value()->clone() );
     32                }
    3333
    34     void InitExpander::visit( ListInit * listInit ) {
    35       // xxx - for now, assume no nested list inits
    36       std::list<Initializer*>::iterator it = listInit->begin_initializers();
    37       for ( ; it != listInit->end_initializers(); ++it ) {
    38         (*it)->accept( *this );
    39       }
    40     }
    41   }
     34                void InitExpander::visit( ListInit * listInit ) {
     35                        // xxx - for now, assume no nested list inits
     36                        std::list<Initializer*>::iterator it = listInit->begin_initializers();
     37                        for ( ; it != listInit->end_initializers(); ++it ) {
     38                                (*it)->accept( *this );
     39                        }
     40                }
     41        }
    4242
    43   std::list< Expression * > makeInitList( Initializer * init ) {
    44     InitExpander expander;
    45     maybeAccept( init, expander );
    46     return expander.argList;
    47   }
     43        std::list< Expression * > makeInitList( Initializer * init ) {
     44                InitExpander expander;
     45                maybeAccept( init, expander );
     46                return expander.argList;
     47        }
    4848
    49   bool isDesignated( Initializer * init ) {
    50     HasDesignations finder;
    51     maybeAccept( init, finder );
    52     return finder.hasDesignations;
    53   }
     49        bool isDesignated( Initializer * init ) {
     50                HasDesignations finder;
     51                maybeAccept( init, finder );
     52                return finder.hasDesignations;
     53        }
    5454
    55   bool tryConstruct( ObjectDecl * objDecl ) {
    56     return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    57       (objDecl->get_init() == NULL ||
    58         ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
    59       ! isDesignated( objDecl->get_init() );
    60   }
     55        bool tryConstruct( ObjectDecl * objDecl ) {
     56                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
     57                        (objDecl->get_init() == NULL ||
     58                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
     59                        ! isDesignated( objDecl->get_init() );
     60        }
    6161
    62   bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
    63     if ( stmt == NULL ) return false;
    64     if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    65       ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
    66       assert( appExpr );
    67       VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
    68       assert( function );
    69       // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    70       // will call all member dtors, and some members may have a user defined dtor.
    71       FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
    72       assert( funcType );
    73       return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
    74     } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
    75       // could also be a compound statement with a loop, in the case of an array
    76       assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
    77       ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
    78       assert( forStmt && forStmt->get_body() );
    79       return isInstrinsicSingleArgCallStmt( forStmt->get_body() );
    80     } else {
    81       // should never get here
    82       assert( false && "encountered unknown call statement" );
    83     }
    84   }
     62        Expression * getCtorDtorCall( Statement * stmt ) {
     63                if ( stmt == NULL ) return NULL;
     64                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
     65                        return exprStmt->get_expr();
     66                } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
     67                        // could also be a compound statement with a loop, in the case of an array
     68                        assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
     69                        ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
     70                        assert( forStmt && forStmt->get_body() );
     71                        return getCtorDtorCall( forStmt->get_body() );
     72                } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
     73                        return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
     74                } else {
     75                        // should never get here
     76                        assert( false && "encountered unknown call statement" );
     77                }
     78        }
     79
     80        bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
     81                Expression * callExpr = getCtorDtorCall( stmt );
     82                if ( ! callExpr ) return false;
     83                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
     84                assert( appExpr );
     85                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     86                assert( function );
     87                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
     88                // will call all member dtors, and some members may have a user defined dtor.
     89                FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
     90                assert( funcType );
     91                return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
     92        }
     93
     94        namespace {
     95                template<typename CallExpr>
     96                Expression *& callArg( CallExpr * callExpr, unsigned int pos ) {
     97                        if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
     98                        for ( Expression *& arg : callExpr->get_args() ) {
     99                                if ( pos == 0 ) return arg;
     100                                pos--;
     101                        }
     102                        assert( false );
     103                }
     104        }
     105
     106        Expression *& getCallArg( Expression * callExpr, unsigned int pos ) {
     107                if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) {
     108                        return callArg( appExpr, pos );
     109                } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
     110                        return callArg( untypedExpr, pos );
     111                } else {
     112                        assert( false && "Unexpected expression type passed to getCallArg" );
     113                }
     114        }
     115
     116        namespace {
     117                template<typename CallExpr>
     118                std::string funcName( CallExpr * expr ) {
     119                        Expression * func = expr->get_function();
     120                        if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( func ) ) {
     121                                return nameExpr->get_name();
     122                        } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) {
     123                                return varExpr->get_var()->get_name();
     124                        } else {
     125                                assert( false && "Unexpected expression type being called as a function in call expression" );
     126                        }
     127                }
     128        }
     129
     130        std::string getFunctionName( Expression * expr ) {
     131                if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
     132                        return funcName( appExpr );
     133                } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * > ( expr ) ) {
     134                        return funcName( untypedExpr );
     135                } else {
     136                        assert( false && "Unexpected expression type passed to getFunctionName" );
     137                }
     138        }
     139
     140        Type * getPointerBase( Type * type ) {
     141                if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
     142                        return ptrType->get_base();
     143                } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
     144                        return arrayType->get_base();
     145                } else {
     146                        return NULL;
     147                }
     148        }
     149
     150        Type * isPointerType( Type * type ) {
     151                if ( getPointerBase( type ) ) return type;
     152                else return NULL;
     153        }
    85154}
  • src/InitTweak/InitTweak.h

    rafab6dc r38bfe32a  
    3939  /// Currently has assertions that make it less than fully general.
    4040  bool isInstrinsicSingleArgCallStmt( Statement * expr );
     41
     42  /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
     43  Expression * getCtorDtorCall( Statement * stmt );
     44
     45  /// returns the name of the function being called
     46  std::string getFunctionName( Expression * expr );
     47
     48  /// returns the argument to a call expression in position N indexed from 0
     49  Expression *& getCallArg( Expression * callExpr, unsigned int pos );
     50
     51  /// returns the base type of a PointerType or ArrayType, else returns NULL
     52  Type * getPointerBase( Type * );
     53
     54  /// returns the argument if it is a PointerType or ArrayType, else returns NULL
     55  Type * isPointerType( Type * );
    4156} // namespace
    4257
  • src/Makefile.in

    rafab6dc r38bfe32a  
    195195        SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
    196196        SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
     197        SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
    197198        Tuples/driver_cfa_cpp-Mutate.$(OBJEXT) \
    198199        Tuples/driver_cfa_cpp-AssignExpand.$(OBJEXT) \
     
    383384        SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    384385        SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
    385         SynTree/TypeSubstitution.cc Tuples/Mutate.cc \
    386         Tuples/AssignExpand.cc Tuples/FunctionFixer.cc \
    387         Tuples/TupleAssignment.cc Tuples/FunctionChecker.cc \
    388         Tuples/NameMatcher.cc
     386        SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
     387        Tuples/Mutate.cc Tuples/AssignExpand.cc \
     388        Tuples/FunctionFixer.cc Tuples/TupleAssignment.cc \
     389        Tuples/FunctionChecker.cc Tuples/NameMatcher.cc
    389390MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    390391        ${cfa_cpplib_PROGRAMS}}
     
    755756SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    756757        SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
     758SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
     759        SynTree/$(DEPDIR)/$(am__dirstamp)
    757760Tuples/$(am__dirstamp):
    758761        @$(MKDIR_P) Tuples
     
    852855        -rm -f SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT)
    853856        -rm -f SynTree/driver_cfa_cpp-AttrType.$(OBJEXT)
     857        -rm -f SynTree/driver_cfa_cpp-Attribute.$(OBJEXT)
    854858        -rm -f SynTree/driver_cfa_cpp-BasicType.$(OBJEXT)
    855859        -rm -f SynTree/driver_cfa_cpp-CommaExpr.$(OBJEXT)
     
    961965@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po@am__quote@
    962966@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po@am__quote@
     967@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po@am__quote@
    963968@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po@am__quote@
    964969@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po@am__quote@
     
    23962401@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    23972402@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeSubstitution.obj `if test -f 'SynTree/TypeSubstitution.cc'; then $(CYGPATH_W) 'SynTree/TypeSubstitution.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeSubstitution.cc'; fi`
     2403
     2404SynTree/driver_cfa_cpp-Attribute.o: SynTree/Attribute.cc
     2405@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc
     2406@am__fastdepCXX_TRUE@   $(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po
     2407@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.o' libtool=no @AMDEPBACKSLASH@
     2408@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2409@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc
     2410
     2411SynTree/driver_cfa_cpp-Attribute.obj: SynTree/Attribute.cc
     2412@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
     2413@am__fastdepCXX_TRUE@   $(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po
     2414@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.obj' libtool=no @AMDEPBACKSLASH@
     2415@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     2416@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
    23982417
    23992418Tuples/driver_cfa_cpp-Mutate.o: Tuples/Mutate.cc
  • src/ResolvExpr/AlternativeFinder.cc

    rafab6dc r38bfe32a  
    3939#include "Tuples/NameMatcher.h"
    4040#include "Common/utility.h"
     41#include "InitTweak/InitTweak.h"
    4142
    4243extern bool resolvep;
     
    546547
    547548                {
    548                         NameExpr *fname = 0;;
    549                         if ( ( fname = dynamic_cast<NameExpr *>( untypedExpr->get_function()))
    550                                  && ( fname->get_name() == std::string("&&")) ) {
     549                        std::string fname = InitTweak::getFunctionName( untypedExpr );
     550                        if ( fname == "&&" ) {
    551551                                VoidType v = Type::Qualifiers();                // resolve to type void *
    552552                                PointerType pt( Type::Qualifiers(), v.clone() );
  • src/ResolvExpr/CommonType.cc

    rafab6dc r38bfe32a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CommonType.cc -- 
     7// CommonType.cc --
    88//
    99// Author           : Richard C. Bilson
     
    134134                                result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
    135135                        } // if
     136                } else if ( EnumInstType *enumInstType = dynamic_cast< EnumInstType * > ( type2 ) ) {
     137                        // use signed int in lieu of the enum type
     138                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
     139                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= enumInstType->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= enumInstType->get_qualifiers() ) || widenSecond ) ) {
     140                                result = new BasicType( basicType->get_qualifiers() + enumInstType->get_qualifiers(), newType );
     141                        } // if
    136142                } // if
    137143        }
     
    183189        }
    184190
    185         void CommonType::visit( EnumInstType *aggregateUseType ) {
     191        void CommonType::visit( EnumInstType *enumInstType ) {
     192                if ( dynamic_cast< BasicType * >( type2 ) ) {
     193                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
     194                        Type * temp = type2;
     195                        type2 = enumInstType;
     196                        temp->accept( *this );
     197                        type2 = temp;
     198                } // if
    186199        }
    187200
  • src/ResolvExpr/ConversionCost.cc

    rafab6dc r38bfe32a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ConversionCost.cc -- 
     7// ConversionCost.cc --
    88//
    99// Author           : Richard C. Bilson
     
    157157                                cost = Cost( 0, 0, tableResult );
    158158                        } // if
    159                 } // if
     159                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     160                        // xxx - not positive this is correct, but appears to allow casting int => enum
     161                        cost = Cost( 1, 0, 0 );
     162    } // if
    160163        }
    161164
  • src/ResolvExpr/Resolver.cc

    rafab6dc r38bfe32a  
    3838                virtual void visit( ObjectDecl *functionDecl );
    3939                virtual void visit( TypeDecl *typeDecl );
     40                virtual void visit( EnumDecl * enumDecl );
    4041
    4142                virtual void visit( ArrayType * at );
     
    5253                virtual void visit( BranchStmt *branchStmt );
    5354                virtual void visit( ReturnStmt *returnStmt );
     55                virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
    5456
    5557                virtual void visit( SingleInit *singleInit );
     
    6567                Type *initContext;
    6668                Type *switchType;
     69                bool inEnumDecl = false;
    6770        };
    6871
     
    177180                Type *temp = initContext;
    178181                initContext = new_type;
     182                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     183                        // enumerator initializers should not use the enum type to initialize, since
     184                        // the enum type is still incomplete at this point. Use signed int instead.
     185                        initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     186                }
    179187                SymTab::Indexer::visit( objectDecl );
     188                if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     189                        // delete newly created signed int type
     190                        delete initContext;
     191                }
    180192                initContext = temp;
    181193        }
     
    215227                SymTab::Indexer::visit( functionDecl );
    216228                functionReturn = oldFunctionReturn;
     229        }
     230
     231        void Resolver::visit( EnumDecl * enumDecl ) {
     232                // in case we decide to allow nested enums
     233                bool oldInEnumDecl = inEnumDecl;
     234                inEnumDecl = true;
     235                SymTab::Indexer::visit( enumDecl );
     236                inEnumDecl = oldInEnumDecl;
    217237        }
    218238
     
    492512                } catch ( SemanticError ) {
    493513                        // no alternatives for the constructor initializer - fallback on C-style initializer
    494                         // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     514                        // xxx - not sure if this makes a ton of sense - should maybe never be able to have this situation?
    495515                        fallbackInit( ctorInit );
    496516                        return;
     
    513533                }
    514534        }
     535
     536        void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
     537                // before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
     538                // Do this through a cast expression to greatly simplify the code.
     539                Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
     540                assert( callExpr );
     541                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
     542                Type * type = 0;
     543
     544                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     545                // includes an untyped '+' expression.
     546                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     547                        // constructee is <array>+<index>
     548                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     549                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     550                        assert( dynamic_cast< VariableExpr * >( arr ) );
     551                        assert( arr && arr->get_results().size() == 1 );
     552                        type = arr->get_results().front()->clone();
     553                } else {
     554                        // otherwise, constructing a plain object, which means the object's address is being taken.
     555                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     556                        // type of the VariableExpr to do so.
     557                        assert( constructee->get_results().size() == 1 );
     558                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     559                        assert( addrExpr && addrExpr->get_results().size() == 1);
     560                        type = addrExpr->get_results().front()->clone();
     561                }
     562                // cast to T* with qualifiers removed.
     563                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     564                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     565                // remove lvalue as a qualifier, this can change to
     566                //   type->get_qualifiers() = Type::Qualifiers();
     567                Type * base = InitTweak::getPointerBase( type );
     568                assert( base );
     569                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     570                // if pointer has lvalue qualifier, cast won't appear in output
     571                type->set_isLvalue( false );
     572                constructee = new CastExpr( constructee, type );
     573
     574                // finally, resolve the ctor/dtor
     575                impCtorDtorStmt->get_callStmt()->accept( *this );
     576        }
    515577} // namespace ResolvExpr
    516578
  • src/SymTab/Autogen.cc

    rafab6dc r38bfe32a  
    102102                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    103103
     104                ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType ), 0 );
     105                assignType->get_parameters().push_back( dstParam );
     106
     107                // void ?{}(E *); void ^?{}(E *);
     108                FunctionType * ctorType = assignType->clone();
     109                FunctionType * dtorType = assignType->clone();
     110
     111                ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     112                assignType->get_parameters().push_back( srcParam );
     113                // void ?{}(E *, E);
     114                FunctionType *copyCtorType = assignType->clone();
     115
     116                // T ?=?(E *, E);
    104117                ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    105118                assignType->get_returnVals().push_back( returnVal );
    106119
    107                 // need two assignment operators with different types
    108                 FunctionType * assignType2 = assignType->clone();
    109 
    110                 // E ?=?(E volatile *, E)
    111                 Type *etype = refType->clone();
    112                 // etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
    113 
    114                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
    115                 assignType->get_parameters().push_back( dstParam );
    116 
    117                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
    118                 assignType->get_parameters().push_back( srcParam );
    119 
    120                 // E ?=?(E volatile *, int)
    121                 assignType2->get_parameters().push_back( dstParam->clone() );
    122                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    123                 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    124                 assignType2->get_parameters().push_back( srcParam2 );
     120                // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?
     121                // right now these cases work, but that might change.
    125122
    126123                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    127124                // because each unit generates copies of the default routines for each aggregate.
    128 
    129                 // since there is no definition, these should not be inline
    130                 // make these intrinsic so that the code generator does not make use of them
    131                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
     125                // xxx - Temporary: make these functions intrinsic so they codegen as C assignment.
     126                // Really they're something of a cross between instrinsic and autogen, so should
     127                // probably make a new linkage type
     128                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, new CompoundStmt( noLabels ), true, false );
     129                FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, ctorType, new CompoundStmt( noLabels ), true, false );
     130                FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, copyCtorType, new CompoundStmt( noLabels ), true, false );
     131                FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, dtorType, new CompoundStmt( noLabels ), true, false );
    132132                assignDecl->fixUniqueId();
    133                 FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
    134                 assignDecl2->fixUniqueId();
    135 
    136                 // these should be built in the same way that the prelude
    137                 // functions are, so build a list containing the prototypes
    138                 // and allow MakeLibCfa to autogenerate the bodies.
    139                 std::list< Declaration * > assigns;
    140                 assigns.push_back( assignDecl );
    141                 assigns.push_back( assignDecl2 );
    142 
    143                 LibCfa::makeLibCfa( assigns );
    144 
    145                 // need to remove the prototypes, since this may be nested in a routine
    146                 for (int start = 0, end = assigns.size()/2; start < end; start++) {
    147                         delete assigns.front();
    148                         assigns.pop_front();
    149                 } // for
    150 
    151                 declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
     133                ctorDecl->fixUniqueId();
     134                copyCtorDecl->fixUniqueId();
     135                dtorDecl->fixUniqueId();
     136
     137                // enum copy construct and assignment is just C-style assignment.
     138                // this looks like a bad recursive call, but code gen will turn it into
     139                // a C-style assignment.
     140                // This happens before function pointer type conversion, so need to do it manually here
     141                VariableExpr * assignVarExpr = new VariableExpr( assignDecl );
     142                Type *& assignVarExprType = assignVarExpr->get_results().front();
     143                assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType );
     144                ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr );
     145                assignExpr->get_args().push_back( new VariableExpr( dstParam ) );
     146                assignExpr->get_args().push_back( new VariableExpr( srcParam ) );
     147
     148                // body is either return stmt or expr stmt
     149                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, assignExpr ) );
     150                copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, assignExpr->clone() ) );
     151
     152                declsToAdd.push_back( assignDecl );
     153                declsToAdd.push_back( ctorDecl );
     154                declsToAdd.push_back( copyCtorDecl );
     155                declsToAdd.push_back( dtorDecl );
    152156        }
    153157
     
    488492                type->get_parameters().push_back( dst );
    489493                type->get_parameters().push_back( src );
    490                 FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
     494                FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, true, false );
    491495                declsToAdd.push_back( func );
    492496        }
  • src/SymTab/Validate.cc

    rafab6dc r38bfe32a  
    279279        void Pass1::visit( EnumDecl *enumDecl ) {
    280280                // Set the type of each member of the enumeration to be EnumConstant
    281 
    282281                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    283282                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    284283                        assert( obj );
    285                         // obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
    286                         BasicType * enumType = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
    287                         obj->set_type( enumType ) ;
     284                        obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
    288285                } // for
    289286                Parent::visit( enumDecl );
  • src/SynTree/Declaration.h

    rafab6dc r38bfe32a  
    115115        typedef DeclarationWithType Parent;
    116116  public:
    117         // temporary - merge this into general GCC attributes
    118         struct Attribute {
    119                 enum Type {
    120                         NoAttribute, Constructor, Destructor,
    121                 } type;
    122                 enum Priority {
    123                         // priorities 0-100 are reserved by gcc, so it's okay to use 100 an exceptional case
    124                         Default = 100, High,
    125                 } priority;
    126                 Attribute(Type t = NoAttribute, Priority p = Default) : type(t), priority(p) {};
    127         };
    128 
    129         FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute = Attribute() );
     117        FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, const std::list< Attribute * > attributes = std::list< Attribute * >() );
    130118        FunctionDecl( const FunctionDecl &other );
    131119        virtual ~FunctionDecl();
     
    140128        std::list< std::string >& get_oldIdents() { return oldIdents; }
    141129        std::list< Declaration* >& get_oldDecls() { return oldDecls; }
    142         Attribute get_attribute() const { return attribute; }
    143         void set_attribute( Attribute newValue ) { attribute = newValue; }
     130        std::list< Attribute * >& get_attributes() { return attributes; }
    144131
    145132        virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
     
    153140        std::list< std::string > oldIdents;
    154141        std::list< Declaration* > oldDecls;
    155         Attribute attribute;
     142        std::list< Attribute * > attributes;
    156143};
    157144
  • src/SynTree/FunctionDecl.cc

    rafab6dc r38bfe32a  
    1919#include "Statement.h"
    2020#include "Type.h"
     21#include "Attribute.h"
    2122#include "Common/utility.h"
    2223
    23 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute )
    24                 : Parent( name, sc, linkage ), type( type ), statements( statements ), attribute( attribute ) {
     24FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, std::list< Attribute * > attributes )
     25                : Parent( name, sc, linkage ), type( type ), statements( statements ), attributes( attributes ) {
    2526        set_isInline( isInline );
    2627        set_isNoreturn( isNoreturn );
     
    3233
    3334FunctionDecl::FunctionDecl( const FunctionDecl &other )
    34         : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), attribute( other.attribute ) {
     35        : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
     36                cloneAll( other.attributes, attributes );
    3537}
    3638
     
    3840        delete type;
    3941        delete statements;
     42        deleteAll( attributes );
    4043}
    4144
     
    6568                os << "_Noreturn ";
    6669        } // if
    67         switch ( attribute.type ) {
    68                 case Attribute::Constructor:
    69                         os << "Global Constructor ";
    70                         break;
    71                 case Attribute::Destructor:
    72                         os << "Global Destructor ";
    73                         break;
    74                 default:
    75                         break;
    76         }
    77         if ( attribute.priority != Attribute::Default ) {
    78                 os << "with priority " << attribute.priority << " ";
    79         }
     70
     71        printAll( attributes, os, indent );
     72
    8073        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    8174                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
     
    118111                os << "_Noreturn ";
    119112        } // if
    120         switch ( attribute.type ) {
    121                 case Attribute::Constructor:
    122                         os << " Global Constructor ";
    123                         break;
    124                 case Attribute::Destructor:
    125                         os << " Global Destructor ";
    126                         break;
    127                 default:
    128                         break;
    129         }
    130         if ( attribute.priority != Attribute::Default ) {
    131                 os << "with priority " << attribute.priority << " ";
    132         }
     113
     114        // xxx - should printShort print attributes?
     115
    133116        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    134117                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
  • src/SynTree/Initializer.cc

    rafab6dc r38bfe32a  
    2020
    2121Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
     22Initializer::Initializer( const Initializer & other ) : maybeConstructed( other.maybeConstructed ) {
     23}
     24
    2225
    2326Initializer::~Initializer() {}
     
    3942}
    4043
    41 SingleInit::~SingleInit() {}
    42 
    43 SingleInit *SingleInit::clone() const { return new SingleInit( *this); }
     44SingleInit::~SingleInit() {
     45        deleteAll(designators);
     46}
    4447
    4548void SingleInit::print( std::ostream &os, int indent ) {
     
    5861
    5962ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
    60         : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
     63        : Initializer( maybeConstructed ), initializers( _initializers ), designators( _designators ) {
    6164}
    6265
    63 ListInit::~ListInit() {}
    64 
    65 ListInit *ListInit::clone() const {
    66         return new ListInit( *this );
     66ListInit::~ListInit() {
     67        deleteAll( initializers );
     68        deleteAll( designators );
    6769}
    6870
     
    8587
    8688ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
     89ConstructorInit::ConstructorInit( const ConstructorInit &other ) : Initializer( other ), ctor( maybeClone( other.ctor ) ), dtor( maybeClone( other.dtor ) ), init( maybeClone( other.init ) ) {
     90}
     91
    8792ConstructorInit::~ConstructorInit() {
    8893        delete ctor;
     94        delete dtor;
    8995        delete init;
    90 }
    91 
    92 ConstructorInit *ConstructorInit::clone() const {
    93         return new ConstructorInit( *this );
    9496}
    9597
  • src/SynTree/Initializer.h

    rafab6dc r38bfe32a  
    2020#include "Visitor.h"
    2121#include "Mutator.h"
     22#include "Type.h"
    2223
    2324#include <cassert>
     
    2829        //      Initializer( std::string _name = std::string(""), int _pos = 0 );
    2930        Initializer( bool maybeConstructed );
     31        Initializer( const Initializer & other );
    3032        virtual ~Initializer();
    3133
     
    6870        std::list<Expression *> &get_designators() { return designators; }
    6971
    70         virtual SingleInit *clone() const;
     72        virtual SingleInit *clone() const { return new SingleInit( *this); }
    7173        virtual void accept( Visitor &v ) { v.visit( this ); }
    7274        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     
    9496        std::list<Initializer*>::iterator end_initializers() { return initializers.end(); }
    9597
    96         virtual ListInit *clone() const;
     98        virtual ListInit *clone() const { return new ListInit( *this ); }
    9799        virtual void accept( Visitor &v ) { v.visit( this ); }
    98100        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     
    108110  public:
    109111        ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
     112        ConstructorInit( const ConstructorInit &other );
    110113        virtual ~ConstructorInit();
    111114
     
    117120        Initializer * get_init() const { return init; }
    118121
    119         virtual ConstructorInit *clone() const;
     122        ConstructorInit *clone() const { return new ConstructorInit( *this ); }
    120123        virtual void accept( Visitor &v ) { v.visit( this ); }
    121124        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
  • src/SynTree/Mutator.cc

    rafab6dc r38bfe32a  
    182182}
    183183
     184Statement *Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
     185        impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) );
     186        return impCtorDtorStmt;
     187}
     188
    184189Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
    185190        mutateAll( applicationExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    rafab6dc r38bfe32a  
    5252        virtual NullStmt* mutate( NullStmt *nullStmt );
    5353        virtual Statement* mutate( DeclStmt *declStmt );
     54        virtual Statement* mutate( ImplicitCtorDtorStmt *impCtorDtorStmt );
    5455
    5556        virtual Expression* mutate( ApplicationExpr *applicationExpr );
  • src/SynTree/Statement.cc

    rafab6dc r38bfe32a  
    358358
    359359void CatchStmt::print( std::ostream &os, int indent ) const {
    360         os << string( indent, ' ' ) << "Catch Statement" << endl;
     360        os << "Catch Statement" << endl;
    361361
    362362        os << string( indent, ' ' ) << "... catching" << endl;
     
    383383
    384384void FinallyStmt::print( std::ostream &os, int indent ) const {
    385         os << string( indent, ' ' ) << "Finally Statement" << endl;
     385        os << "Finally Statement" << endl;
    386386        os << string( indent + 2, ' ' ) << "with block: " << endl;
    387387        block->print( os, indent + 4 );
     
    393393void NullStmt::print( std::ostream &os, int indent ) const {
    394394        os << "Null Statement" << endl ;
     395}
     396
     397ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( Statement * callStmt ) : Statement( std::list<Label>() ), callStmt( callStmt ) {
     398        assert( callStmt );
     399}
     400
     401ImplicitCtorDtorStmt::ImplicitCtorDtorStmt( const ImplicitCtorDtorStmt & other ) : Statement( other ), callStmt( other.callStmt ) {
     402}
     403
     404ImplicitCtorDtorStmt::~ImplicitCtorDtorStmt() {
     405}
     406
     407void ImplicitCtorDtorStmt::print( std::ostream &os, int indent ) const {
     408        os << "Implicit Ctor Dtor Statement" << endl;
     409        os << string( indent + 2, ' ' ) << "with Ctor/Dtor: ";
     410        callStmt->print( os, indent + 2);
     411        os << endl;
    395412}
    396413
  • src/SynTree/Statement.h

    rafab6dc r38bfe32a  
    2121#include "Mutator.h"
    2222#include "Common/SemanticError.h"
     23#include "Type.h"
    2324
    2425class Statement {
     
    394395        virtual ~DeclStmt();
    395396
    396         Declaration *get_decl() { return decl; }
     397        Declaration *get_decl() const { return decl; }
    397398        void set_decl( Declaration *newValue ) { decl = newValue; }
    398399
     
    404405        Declaration *decl;
    405406};
     407
     408
     409/// represents an implicit application of a constructor or destructor. Qualifiers are replaced
     410/// immediately before and after the call so that qualified objects can be constructed
     411/// with the same functions as unqualified objects.
     412class ImplicitCtorDtorStmt : public Statement {
     413  public:
     414        ImplicitCtorDtorStmt( Statement * callStmt );
     415        ImplicitCtorDtorStmt( const ImplicitCtorDtorStmt & other );
     416        virtual ~ImplicitCtorDtorStmt();
     417
     418        Statement *get_callStmt() const { return callStmt; }
     419        void set_callStmt( Statement * newValue ) { callStmt = newValue; }
     420
     421        virtual ImplicitCtorDtorStmt *clone() const { return new ImplicitCtorDtorStmt( *this ); }
     422        virtual void accept( Visitor &v ) { v.visit( this ); }
     423        virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     424        virtual void print( std::ostream &os, int indent = 0 ) const;
     425
     426  private:
     427        // Non-owned pointer to the constructor/destructor statement
     428        Statement * callStmt;
     429};
     430
    406431
    407432std::ostream & operator<<( std::ostream & out, Statement * statement );
  • src/SynTree/SynTree.h

    rafab6dc r38bfe32a  
    5656class DeclStmt;
    5757class NullStmt;
     58class ImplicitCtorDtorStmt;
    5859
    5960class Expression;
     
    117118class TypeSubstitution;
    118119
     120// gcc attribute
     121class Attribute;
     122
    119123#endif // SYNTREE_H
    120124
  • src/SynTree/Type.cc

    rafab6dc r38bfe32a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Type.cc -- 
     7// Type.cc --
    88//
    99// Author           : Richard C. Bilson
     
    5454}
    5555
     56void Type::Qualifiers::print( std::ostream &os, int indent ) const {
     57        if ( isConst ) {
     58                os << "const ";
     59        } // if
     60        if ( isVolatile ) {
     61                os << "volatile ";
     62        } // if
     63        if ( isRestrict ) {
     64                os << "restrict ";
     65        } // if
     66        if ( isLvalue ) {
     67                os << "lvalue ";
     68        } // if
     69        if ( isAtomic ) {
     70                os << "_Atomic ";
     71        } // if
     72        if ( isAttribute ) {
     73                os << "__attribute(( )) ";
     74        } // if
     75}
     76
    5677void Type::print( std::ostream &os, int indent ) const {
    5778        if ( ! forall.empty() ) {
     
    6081                os << std::string( indent+2, ' ' );
    6182        } // if
    62         if ( tq.isConst ) {
    63                 os << "const ";
    64         } // if
    65         if ( tq.isVolatile ) {
    66                 os << "volatile ";
    67         } // if
    68         if ( tq.isRestrict ) {
    69                 os << "restrict ";
    70         } // if
    71         if ( tq.isLvalue ) {
    72                 os << "lvalue ";
    73         } // if
    74         if ( tq.isAtomic ) {
    75                 os << "_Atomic ";
    76         } // if
    77         if ( tq.isAttribute ) {
    78                 os << "__attribute(( )) ";
    79         } // if
     83        tq.print( os, indent );
    8084}
    8185
  • src/SynTree/Type.h

    rafab6dc r38bfe32a  
    3636                bool operator<( const Qualifiers &other );
    3737                bool operator>( const Qualifiers &other );
     38                void print( std::ostream &os, int indent = 0 ) const;
    3839
    3940                bool isConst;
  • src/SynTree/Visitor.cc

    rafab6dc r38bfe32a  
    152152}
    153153
     154void Visitor::visit( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
     155        maybeAccept( impCtorDtorStmt->get_callStmt(), *this );
     156}
     157
    154158void Visitor::visit( ApplicationExpr *applicationExpr ) {
    155159        acceptAll( applicationExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    rafab6dc r38bfe32a  
    5252        virtual void visit( NullStmt *nullStmt );
    5353        virtual void visit( DeclStmt *declStmt );
     54        virtual void visit( ImplicitCtorDtorStmt *impCtorDtorStmt );
    5455
    5556        virtual void visit( ApplicationExpr *applicationExpr );
  • src/SynTree/module.mk

    rafab6dc r38bfe32a  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    4646       SynTree/Visitor.cc \
    4747       SynTree/Mutator.cc \
    48        SynTree/TypeSubstitution.cc
     48       SynTree/TypeSubstitution.cc \
     49       SynTree/Attribute.cc
    4950
  • src/examples/avltree/avl-private.h

    rafab6dc r38bfe32a  
     1#ifndef AVL_PRIVATE_H
    12#include "avl.h"
    23
     
    1314forall(otype K | Comparable(K), otype V)
    1415int height(tree(K, V) * t);
     16
     17#endif
Note: See TracChangeset for help on using the changeset viewer.