Changeset f9cebb5


Ignore:
Timestamp:
Aug 4, 2016, 4:10:06 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
4819cac
Parents:
73bf8cf
Message:

add gcc attributes to ObjectDecl?, hoist destructed static variables, add breaks to end of generated switch

Location:
src
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r73bf8cf rf9cebb5  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : 
     11// Last Modified By :
    1212// Last Modified On : Sun Jul 31 08:42:18 2016
    1313// Update Count     : 345
     
    148148        void CodeGenerator::visit( ObjectDecl *objectDecl ) {
    149149                extension( objectDecl );
     150                genAttributes( objectDecl->get_attributes() );
     151
    150152                handleStorageClass( objectDecl );
    151153                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
  • src/InitTweak/FixGlobalInit.cc

    r73bf8cf rf9cebb5  
    107107
    108108                        Statement * dtor = ctorInit->get_dtor();
    109                         if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
     109                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    110110                                // don't need to call intrinsic dtor, because it does nothing, but
    111111                                // non-intrinsic dtors must be called
  • src/InitTweak/FixInit.cc

    r73bf8cf rf9cebb5  
    2626#include "SynTree/Type.h"
    2727#include "SynTree/Expression.h"
     28#include "SynTree/Attribute.h"
    2829#include "SynTree/Statement.h"
    2930#include "SynTree/Initializer.h"
     
    208209                                try {
    209210                                        *i = maybeMutate( *i, fixer );
    210                                         // if (! fixer.staticDtorDecls.empty() ) {
    211                                                 translationUnit.splice( i, fixer.staticDtorDecls );
    212                                         // }
     211                                        translationUnit.splice( i, fixer.staticDtorDecls );
    213212                                } catch( SemanticError &e ) {
    214213                                        errors.append( e );
     
    446445                                        if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
    447446                                                // originally wanted to take advantage of gcc nested functions, but
    448                                                 // we get memory errors with this approach. To remedy this, create a
    449                                                 // global static pointer that is set to refer to the object and make
    450                                                 // the dtor-caller function global so that.
     447                                                // we get memory errors with this approach. To remedy this, the static
     448                                                // variable is hoisted when the destructor needs to be called.
    451449                                                //
    452450                                                // generate:
    453                                                 // T * __objName_static_ptrN;
     451                                                // static T __objName_static_varN;
    454452                                                // void __objName_dtor_atexitN() {
    455                                                 //   __dtor(__objName_static_ptrN);
     453                                                //   __dtor__...;
    456454                                                // }
    457455                                                // int f(...) {
    458456                                                //   ...
    459                                                 //   static T __objName;
    460457                                                //   static bool __objName_uninitialized = true;
    461458                                                //   if (__objName_uninitialized) {
    462                                                 //     __objName_ptr = &__objName;
    463459                                                //     __ctor(__objName);
    464                                                 //     on_exit(__objName_dtor_atexitN, &__objName);
    465460                                                //     __objName_uninitialized = false;
     461                                                //     atexit(__objName_dtor_atexitN);
    466462                                                //   }
    467463                                                //   ...
    468464                                                // }
    469465
    470                                                 static UniqueName ptrNamer( "_static_ptr" );
    471466                                                static UniqueName dtorCallerNamer( "_dtor_atexit" );
    472 
    473                                                 // T * __objName_ptrN
    474                                                 ObjectDecl * objPtr = new ObjectDecl( objDecl->get_mangleName() + ptrNamer.newName(), DeclarationNode::Static, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), objDecl->get_type()->clone() ), 0 );
    475                                                 objPtr->fixUniqueId();
    476 
    477                                                 // void __objName_dtor_atexitN(...) {...}
    478                                                 // need to modify dtor call so that it refers to objPtr, since function will be global
    479                                                 Statement * dtorStmt = ctorInit->get_dtor()->clone();
    480                                                 ApplicationExpr * dtor = dynamic_cast< ApplicationExpr * >( InitTweak::getCtorDtorCall( dtorStmt ) );
    481                                                 assert( dtor );
    482                                                 delete dtor->get_args().front();
    483                                                 dtor->get_args().front() = new VariableExpr( objPtr );
    484 
    485                                                 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
    486                                                 dtorCaller->fixUniqueId();
    487                                                 dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
    488467
    489468                                                // static bool __objName_uninitialized = true
     
    493472                                                isUninitializedVar->fixUniqueId();
    494473
    495                                                 // __objName_static_ptrN = &__objName;
    496                                                 UntypedExpr * ptrAssign = new UntypedExpr( new NameExpr( "?=?" ) );
    497                                                 ptrAssign->get_args().push_back( new VariableExpr( objPtr ) );
    498                                                 ptrAssign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    499 
    500                                                 // atexit(dtor_atexit);
    501                                                 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
    502                                                 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
    503 
    504474                                                // __objName_uninitialized = false;
    505475                                                UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
     
    511481                                                std::list< Statement * > & body = initStmts->get_kids();
    512482                                                body.push_back( ctor );
    513                                                 body.push_back( new ExprStmt( noLabels, ptrAssign ) );
    514                                                 body.push_back( new ExprStmt( noLabels, callAtexit ) );
    515483                                                body.push_back( new ExprStmt( noLabels, setTrue ) );
    516484
     
    520488                                                stmtsToAddAfter.push_back( ifStmt );
    521489
    522                                                 // add pointer and dtor caller decls to list of decls that will be added into global scope
    523                                                 staticDtorDecls.push_back( objPtr );
    524                                                 staticDtorDecls.push_back( dtorCaller );
     490                                                if ( ctorInit->get_dtor() ) {
     491                                                        // if the object has a non-trivial destructor, have to
     492                                                        // hoist it and the object into the global space and
     493                                                        // call the destructor function with atexit.
     494
     495                                                        Statement * dtorStmt = ctorInit->get_dtor()->clone();
     496
     497                                                        // void __objName_dtor_atexitN(...) {...}
     498                                                        FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     499                                                        dtorCaller->fixUniqueId();
     500                                                        dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
     501
     502                                                        // atexit(dtor_atexit);
     503                                                        UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
     504                                                        callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
     505
     506                                                        body.push_back( new ExprStmt( noLabels, callAtexit ) );
     507
     508                                                        // hoist variable and dtor caller decls to list of decls that will be added into global scope
     509                                                        staticDtorDecls.push_back( objDecl );
     510                                                        staticDtorDecls.push_back( dtorCaller );
     511
     512                                                        // need to rename object uniquely since it now appears
     513                                                        // at global scope and there could be multiple function-scoped
     514                                                        // static variables with the same name in different functions.
     515                                                        static UniqueName staticNamer( "_static_var" );
     516                                                        objDecl->set_mangleName( objDecl->get_mangleName() + staticNamer.newName() );
     517
     518                                                        objDecl->set_init( NULL );
     519                                                        ctorInit->set_ctor( NULL );
     520                                                        delete ctorInit;
     521
     522                                                        // xxx - temporary hack: need to return a declaration, but want to hoist the current object out of this scope
     523                                                        // create a new object which is never used
     524                                                        static UniqueName dummyNamer( "_dummy" );
     525                                                        ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), DeclarationNode::Static, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } );
     526                                                        return dummy;
     527                                                }
    525528                                        } else {
    526529                                                stmtsToAddAfter.push_back( ctor );
     
    582585                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    583586                                        Statement * dtor = ctorInit->get_dtor();
    584                                         if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
     587                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    585588                                                // don't need to call intrinsic dtor, because it does nothing, but
    586589                                                // non-intrinsic dtors must be called
  • src/InitTweak/GenInit.cc

    r73bf8cf rf9cebb5  
    172172                // if in function, generate const size_t var
    173173                static UniqueName dimensionName( "_array_dim" );
     174
     175                // C doesn't allow variable sized arrays at global scope or for static variables,
     176                // so don't hoist dimension.
     177                if ( ! inFunction ) return;
     178                if ( storageclass == DeclarationNode::Static ) return;
     179
    174180                if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
    175                         if ( ! inFunction ) return;
    176 
    177181                        if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
    178182
     
    203207                CtorDtor ctordtor;
    204208                mutateAll( translationUnit, ctordtor );
    205         }
    206 
    207         namespace {
    208                 Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
    209                         UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
    210                         expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    211                         expr->get_args().splice( expr->get_args().end(), args );
    212                         return expr;
    213                 }
    214209        }
    215210
  • src/InitTweak/InitTweak.cc

    r73bf8cf rf9cebb5  
    55#include "SynTree/Initializer.h"
    66#include "SynTree/Expression.h"
     7#include "SynTree/Attribute.h"
    78#include "GenPoly/GenPoly.h"
    89
     
    125126
    126127        namespace {
     128                /// given index i, dimension d, initializer init, and callExpr f, generates
     129                ///   if (i < d) f(..., init)
     130                ///   ++i;
     131                /// so that only elements within the range of the array are constructed
    127132                template< typename OutIterator >
    128                 void dothething( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) {
     133                void buildCallExpr( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) {
    129134                        UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") );
    130135                        cond->get_args().push_back( index->clone() );
     
    148153                        Expression * dimension = *idx++;
    149154
     155                        // xxx - may want to eventually issue a warning here if we can detect
     156                        // that the number of elements exceeds to dimension of the array
    150157                        if ( idx == idxEnd ) {
    151158                                if ( ListInit * listInit = dynamic_cast< ListInit * >( init ) ) {
    152159                                        for ( Initializer * init : *listInit ) {
    153                                                 dothething( callExpr->clone(), index, dimension, init, out );
     160                                                buildCallExpr( callExpr->clone(), index, dimension, init, out );
    154161                                        }
    155162                                } else {
    156                                         dothething( callExpr->clone(), index, dimension, init, out );
     163                                        buildCallExpr( callExpr->clone(), index, dimension, init, out );
    157164                                }
    158165                        } else {
     
    166173                                        throw SemanticError( "unbalanced list initializers" );
    167174                                }
     175
     176                                static UniqueName targetLabel( "L__autogen__" );
     177                                Label switchLabel( targetLabel.newName(), 0, std::list< Attribute * >{ new Attribute("unused") } );
    168178                                for ( Initializer * init : *listInit ) {
    169179                                        Expression * condition;
     
    178188                                        std::list< Statement * > stmts;
    179189                                        build( callExpr, idx, idxEnd, init, back_inserter( stmts ) );
     190                                        stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) );
    180191                                        CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts );
    181192                                        branches.push_back( caseStmt );
    182193                                }
    183194                                *out++ = new SwitchStmt( noLabels, index->clone(), branches );
     195                                *out++ = new NullStmt( std::list<Label>{ switchLabel } );
    184196                        }
    185197                }
     
    194206        Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    195207                if ( ! init ) return NULL;
    196                 std::list< Statement * > results;
    197                 build( dst, indices.begin(), indices.end(), init, back_inserter( results ) );
    198                 assert( results.size() <= 1 );
    199                 if ( results.empty() ) {
     208                CompoundStmt * block = new CompoundStmt( noLabels );
     209                build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
     210                if ( block->get_kids().empty() ) {
     211                        delete block;
    200212                        return NULL;
    201213                } else {
    202214                        init = NULL; // init was consumed in creating the list init
    203                         return results.front();
    204                 }
    205                 return ! results.empty() ? results.front() : NULL;
     215                        return block;
     216                }
    206217        }
    207218
     
    280291        }
    281292
    282         bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
     293        bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
    283294                std::list< Expression * > callExprs;
    284295                collectCtorDtorCalls( stmt, callExprs );
  • src/InitTweak/InitTweak.h

    r73bf8cf rf9cebb5  
    4141        /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
    4242        /// Currently has assertions that make it less than fully general.
    43         bool isInstrinsicSingleArgCallStmt( Statement * expr );
     43        bool isIntrinsicSingleArgCallStmt( Statement * expr );
    4444
    4545        /// get all Ctor/Dtor call expressions from a Statement
  • src/Parser/TypeData.cc

    r73bf8cf rf9cebb5  
    510510                return buildVariable();
    511511        } else {
    512                 return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, isInline, isNoreturn );
     512                return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, std::list< Attribute * >(),  isInline, isNoreturn );
    513513        } // if
    514514        return 0;
  • src/ResolvExpr/Resolver.cc

    r73bf8cf rf9cebb5  
    534534                // implicitly generated, there's no way for it to have side effects, so get rid of it
    535535                // to clean up generated code.
    536                 if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     536                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
    537537                        delete ctorInit->get_ctor();
    538538                        ctorInit->set_ctor( NULL );
    539539                }
    540                 if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
     540
     541                // xxx - todo
     542                // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
     543                //      // can reduce the constructor down to a SingleInit using the
     544                //      // second argument from the ctor call
     545                // }
     546
     547                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
    541548                        delete ctorInit->get_dtor();
    542549                        ctorInit->set_dtor( NULL );
  • src/SymTab/Autogen.h

    r73bf8cf rf9cebb5  
    3737        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    3838        template< typename OutputIterator >
    39         void genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
     39        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    4141        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     42        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    4243        template< typename OutputIterator >
    43         void genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
     44        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    4445                // want to be able to generate assignment, ctor, and dtor generically,
    4546                // so fname is either ?=?, ?{}, or ^?{}
     
    6364                fExpr->get_args().push_back( dstParam );
    6465
    65     Statement * listInit = srcParam.buildListInit( fExpr );
    66     if ( listInit ) {
    67       *out++ = listInit;
    68     }
     66                Statement * listInit = srcParam.buildListInit( fExpr );
    6967
    70     std::list< Expression * > args = *++srcParam;
    71     fExpr->get_args().splice( fExpr->get_args().end(), args );
     68                std::list< Expression * > args = *++srcParam;
     69                fExpr->get_args().splice( fExpr->get_args().end(), args );
    7270
    7371                *out++ = new ExprStmt( noLabels, fExpr );
    7472
    75     srcParam.clearArrayIndices();
     73                srcParam.clearArrayIndices();
     74
     75                return listInit;
    7676        }
    7777
     
    125125                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    126126
    127                 // if ( srcParam ) {
    128                 //      UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    129                 //      srcIndex->get_args().push_back( srcParam );
    130                 //      srcIndex->get_args().push_back( new VariableExpr( index ) );
    131                 //      srcParam = srcIndex;
    132                 // }
    133 
    134127                // for stmt's body, eventually containing call
    135128                CompoundStmt * body = new CompoundStmt( noLabels );
    136                 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     129                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
    137130
    138131                // block containing for stmt and index variable
     
    140133                CompoundStmt * block = new CompoundStmt( noLabels );
    141134                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     135                if ( listInit ) block->get_kids().push_back( listInit );
    142136                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    143137
     
    146140
    147141        template< typename OutputIterator >
    148         void genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     142        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    149143                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    150144                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     145                        return 0;
    151146                } else {
    152                         genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     147                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
    153148                }
    154149        }
     
    171166                // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
    172167                assert( stmts.size() <= 1 );
    173     if ( stmts.size() == 1 ) {
    174                 Statement * callStmt = stmts.front();
    175                 if ( addCast ) {
    176                         // implicitly generated ctor/dtor calls should be wrapped
    177                         // so that later passes are aware they were generated.
    178                         // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    179                         // because this causes the address to be taken at codegen, which is illegal in C.
    180                         callStmt = new ImplicitCtorDtorStmt( callStmt );
    181                 }
    182                 *out++ = callStmt;
    183     }
     168                if ( stmts.size() == 1 ) {
     169                        Statement * callStmt = stmts.front();
     170                        if ( addCast ) {
     171                                // implicitly generated ctor/dtor calls should be wrapped
     172                                // so that later passes are aware they were generated.
     173                                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     174                                // because this causes the address to be taken at codegen, which is illegal in C.
     175                                callStmt = new ImplicitCtorDtorStmt( callStmt );
     176                        }
     177                        *out++ = callStmt;
     178                }
    184179        }
    185180} // namespace SymTab
  • src/SynTree/Declaration.cc

    r73bf8cf rf9cebb5  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Declaration.cc -- 
     7// Declaration.cc --
    88//
    99// Author           : Richard C. Bilson
     
    2020#include "Initializer.h"
    2121#include "Type.h"
     22#include "Attribute.h"
    2223#include "Common/utility.h"
    2324
  • src/SynTree/Declaration.h

    r73bf8cf rf9cebb5  
    6464class DeclarationWithType : public Declaration {
    6565  public:
    66         DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage );
     66        DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, const std::list< Attribute * > & attributes );
    6767        DeclarationWithType( const DeclarationWithType &other );
    6868        virtual ~DeclarationWithType();
     
    7575        int get_scopeLevel() const { return scopeLevel; }
    7676        void set_scopeLevel( int newValue ) { scopeLevel = newValue; }
     77
     78        std::list< Attribute * >& get_attributes() { return attributes; }
     79        const std::list< Attribute * >& get_attributes() const { return attributes; }
    7780
    7881        virtual DeclarationWithType *clone() const = 0;
     
    8790        // shadowed identifiers can be accessed
    8891        int scopeLevel = 0;
     92
     93        std::list< Attribute * > attributes;
    8994};
    9095
     
    9297        typedef DeclarationWithType Parent;
    9398  public:
    94         ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline = false, bool isNoreturn = false );
     99        ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, const std::list< Attribute * > attributes = std::list< Attribute * >(), bool isInline = false, bool isNoreturn = false );
    95100        ObjectDecl( const ObjectDecl &other );
    96101        virtual ~ObjectDecl();
     
    131136        std::list< std::string >& get_oldIdents() { return oldIdents; }
    132137        std::list< Declaration* >& get_oldDecls() { return oldDecls; }
    133         std::list< Attribute * >& get_attributes() { return attributes; }
    134138
    135139        virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
     
    143147        std::list< std::string > oldIdents;
    144148        std::list< Declaration* > oldDecls;
    145         std::list< Attribute * > attributes;
    146149};
    147150
  • src/SynTree/DeclarationWithType.cc

    r73bf8cf rf9cebb5  
    1616#include "Declaration.h"
    1717#include "Type.h"
     18#include "Attribute.h"
    1819#include "Common/utility.h"
    1920
    20 DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage )
    21                 : Declaration( name, sc, linkage ) {
     21DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, const std::list< Attribute * > & attributes )
     22                : Declaration( name, sc, linkage ), attributes( attributes ) {
    2223}
    2324
    2425DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
    2526                : Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) {
     27        cloneAll( other.attributes, attributes );
    2628}
    2729
    2830DeclarationWithType::~DeclarationWithType() {
     31        deleteAll( attributes );
    2932}
    3033
  • src/SynTree/FunctionDecl.cc

    r73bf8cf rf9cebb5  
    2323
    2424FunctionDecl::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 ) {
     25                : Parent( name, sc, linkage, attributes ), type( type ), statements( statements ) {
    2626        set_isInline( isInline );
    2727        set_isNoreturn( isNoreturn );
     
    3434FunctionDecl::FunctionDecl( const FunctionDecl &other )
    3535        : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
    36                 cloneAll( other.attributes, attributes );
    3736}
    3837
     
    4039        delete type;
    4140        delete statements;
    42         deleteAll( attributes );
    4341}
    4442
     
    6967        } // if
    7068
    71         printAll( attributes, os, indent );
     69        printAll( get_attributes(), os, indent );
    7270
    7371        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
  • src/SynTree/Label.h

    r73bf8cf rf9cebb5  
    2424class Label {
    2525  public:
    26         Label( const std::string & name = "", Statement * labelled = 0 ) : name( name ), labelled( labelled ) {}
     26        Label( const std::string & name = "", Statement * labelled = 0, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : name( name ), labelled( labelled ), attributes( attributes ) {}
    2727        Label( const char * name, Statement * labelled = 0 ) : name( name ), labelled( labelled ) {}
    2828
  • src/SynTree/ObjectDecl.cc

    r73bf8cf rf9cebb5  
    1818#include "Initializer.h"
    1919#include "Expression.h"
     20#include "Attribute.h"
    2021#include "Common/utility.h"
    2122#include "Statement.h"
    2223
    23 ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn )
    24         : Parent( name, sc, linkage ), type( type ), init( init ), bitfieldWidth( bitfieldWidth ) {
     24ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, const std::list< Attribute * > attributes, bool isInline, bool isNoreturn )
     25        : Parent( name, sc, linkage, attributes ), type( type ), init( init ), bitfieldWidth( bitfieldWidth ) {
    2526        set_isInline( isInline );
    2627        set_isNoreturn( isNoreturn );
     
    4546                os << LinkageSpec::toString( get_linkage() ) << " ";
    4647        } // if
     48
     49        printAll( get_attributes(), os, indent );
    4750
    4851        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
     
    8083        } // if
    8184
     85        // xxx - should printShort print attributes?
     86
    8287        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    8388                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Note: See TracChangeset for help on using the changeset viewer.