Changeset f9cebb5
- Timestamp:
- Aug 4, 2016, 4:10:06 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 4819cac
- Parents:
- 73bf8cf2
- Location:
- src
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r73bf8cf2 rf9cebb5 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 11 // Last Modified By : 12 12 // Last Modified On : Sun Jul 31 08:42:18 2016 13 13 // Update Count : 345 … … 148 148 void CodeGenerator::visit( ObjectDecl *objectDecl ) { 149 149 extension( objectDecl ); 150 genAttributes( objectDecl->get_attributes() ); 151 150 152 handleStorageClass( objectDecl ); 151 153 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); -
src/InitTweak/FixGlobalInit.cc
r73bf8cf2 rf9cebb5 107 107 108 108 Statement * dtor = ctorInit->get_dtor(); 109 if ( dtor && ! isIn strinsicSingleArgCallStmt( dtor ) ) {109 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 110 110 // don't need to call intrinsic dtor, because it does nothing, but 111 111 // non-intrinsic dtors must be called -
src/InitTweak/FixInit.cc
r73bf8cf2 rf9cebb5 26 26 #include "SynTree/Type.h" 27 27 #include "SynTree/Expression.h" 28 #include "SynTree/Attribute.h" 28 29 #include "SynTree/Statement.h" 29 30 #include "SynTree/Initializer.h" … … 208 209 try { 209 210 *i = maybeMutate( *i, fixer ); 210 // if (! fixer.staticDtorDecls.empty() ) { 211 translationUnit.splice( i, fixer.staticDtorDecls ); 212 // } 211 translationUnit.splice( i, fixer.staticDtorDecls ); 213 212 } catch( SemanticError &e ) { 214 213 errors.append( e ); … … 446 445 if ( objDecl->get_storageClass() == DeclarationNode::Static ) { 447 446 // 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. 451 449 // 452 450 // generate: 453 // T * __objName_static_ptrN;451 // static T __objName_static_varN; 454 452 // void __objName_dtor_atexitN() { 455 // __dtor (__objName_static_ptrN);453 // __dtor__...; 456 454 // } 457 455 // int f(...) { 458 456 // ... 459 // static T __objName;460 457 // static bool __objName_uninitialized = true; 461 458 // if (__objName_uninitialized) { 462 // __objName_ptr = &__objName;463 459 // __ctor(__objName); 464 // on_exit(__objName_dtor_atexitN, &__objName);465 460 // __objName_uninitialized = false; 461 // atexit(__objName_dtor_atexitN); 466 462 // } 467 463 // ... 468 464 // } 469 465 470 static UniqueName ptrNamer( "_static_ptr" );471 466 static UniqueName dtorCallerNamer( "_dtor_atexit" ); 472 473 // T * __objName_ptrN474 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 global479 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 );488 467 489 468 // static bool __objName_uninitialized = true … … 493 472 isUninitializedVar->fixUniqueId(); 494 473 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 504 474 // __objName_uninitialized = false; 505 475 UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) ); … … 511 481 std::list< Statement * > & body = initStmts->get_kids(); 512 482 body.push_back( ctor ); 513 body.push_back( new ExprStmt( noLabels, ptrAssign ) );514 body.push_back( new ExprStmt( noLabels, callAtexit ) );515 483 body.push_back( new ExprStmt( noLabels, setTrue ) ); 516 484 … … 520 488 stmtsToAddAfter.push_back( ifStmt ); 521 489 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 } 525 528 } else { 526 529 stmtsToAddAfter.push_back( ctor ); … … 582 585 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 583 586 Statement * dtor = ctorInit->get_dtor(); 584 if ( dtor && ! isIn strinsicSingleArgCallStmt( dtor ) ) {587 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 585 588 // don't need to call intrinsic dtor, because it does nothing, but 586 589 // non-intrinsic dtors must be called -
src/InitTweak/GenInit.cc
r73bf8cf2 rf9cebb5 172 172 // if in function, generate const size_t var 173 173 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 174 180 if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) { 175 if ( ! inFunction ) return;176 177 181 if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist? 178 182 … … 203 207 CtorDtor ctordtor; 204 208 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 }214 209 } 215 210 -
src/InitTweak/InitTweak.cc
r73bf8cf2 rf9cebb5 5 5 #include "SynTree/Initializer.h" 6 6 #include "SynTree/Expression.h" 7 #include "SynTree/Attribute.h" 7 8 #include "GenPoly/GenPoly.h" 8 9 … … 125 126 126 127 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 127 132 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 ) { 129 134 UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") ); 130 135 cond->get_args().push_back( index->clone() ); … … 148 153 Expression * dimension = *idx++; 149 154 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 150 157 if ( idx == idxEnd ) { 151 158 if ( ListInit * listInit = dynamic_cast< ListInit * >( init ) ) { 152 159 for ( Initializer * init : *listInit ) { 153 dothething( callExpr->clone(), index, dimension, init, out );160 buildCallExpr( callExpr->clone(), index, dimension, init, out ); 154 161 } 155 162 } else { 156 dothething( callExpr->clone(), index, dimension, init, out );163 buildCallExpr( callExpr->clone(), index, dimension, init, out ); 157 164 } 158 165 } else { … … 166 173 throw SemanticError( "unbalanced list initializers" ); 167 174 } 175 176 static UniqueName targetLabel( "L__autogen__" ); 177 Label switchLabel( targetLabel.newName(), 0, std::list< Attribute * >{ new Attribute("unused") } ); 168 178 for ( Initializer * init : *listInit ) { 169 179 Expression * condition; … … 178 188 std::list< Statement * > stmts; 179 189 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 190 stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) ); 180 191 CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts ); 181 192 branches.push_back( caseStmt ); 182 193 } 183 194 *out++ = new SwitchStmt( noLabels, index->clone(), branches ); 195 *out++ = new NullStmt( std::list<Label>{ switchLabel } ); 184 196 } 185 197 } … … 194 206 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 195 207 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; 200 212 return NULL; 201 213 } else { 202 214 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 } 206 217 } 207 218 … … 280 291 } 281 292 282 bool isIn strinsicSingleArgCallStmt( Statement * stmt ) {293 bool isIntrinsicSingleArgCallStmt( Statement * stmt ) { 283 294 std::list< Expression * > callExprs; 284 295 collectCtorDtorCalls( stmt, callExprs ); -
src/InitTweak/InitTweak.h
r73bf8cf2 rf9cebb5 41 41 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere. 42 42 /// Currently has assertions that make it less than fully general. 43 bool isIn strinsicSingleArgCallStmt( Statement * expr );43 bool isIntrinsicSingleArgCallStmt( Statement * expr ); 44 44 45 45 /// get all Ctor/Dtor call expressions from a Statement -
src/Parser/TypeData.cc
r73bf8cf2 rf9cebb5 510 510 return buildVariable(); 511 511 } 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 ); 513 513 } // if 514 514 return 0; -
src/ResolvExpr/Resolver.cc
r73bf8cf2 rf9cebb5 534 534 // implicitly generated, there's no way for it to have side effects, so get rid of it 535 535 // to clean up generated code. 536 if ( InitTweak::isIn strinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {536 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) { 537 537 delete ctorInit->get_ctor(); 538 538 ctorInit->set_ctor( NULL ); 539 539 } 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() ) ) { 541 548 delete ctorInit->get_dtor(); 542 549 ctorInit->set_dtor( NULL ); -
src/SymTab/Autogen.h
r73bf8cf2 rf9cebb5 37 37 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 38 38 template< typename OutputIterator > 39 voidgenCall( 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 ); 40 40 41 41 /// 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 42 43 template< typename OutputIterator > 43 voidgenScalarCall( 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 ) { 44 45 // want to be able to generate assignment, ctor, and dtor generically, 45 46 // so fname is either ?=?, ?{}, or ^?{} … … 63 64 fExpr->get_args().push_back( dstParam ); 64 65 65 Statement * listInit = srcParam.buildListInit( fExpr ); 66 if ( listInit ) { 67 *out++ = listInit; 68 } 66 Statement * listInit = srcParam.buildListInit( fExpr ); 69 67 70 71 68 std::list< Expression * > args = *++srcParam; 69 fExpr->get_args().splice( fExpr->get_args().end(), args ); 72 70 73 71 *out++ = new ExprStmt( noLabels, fExpr ); 74 72 75 srcParam.clearArrayIndices(); 73 srcParam.clearArrayIndices(); 74 75 return listInit; 76 76 } 77 77 … … 125 125 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() ); 126 126 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 134 127 // for stmt's body, eventually containing call 135 128 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 ); 137 130 138 131 // block containing for stmt and index variable … … 140 133 CompoundStmt * block = new CompoundStmt( noLabels ); 141 134 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 135 if ( listInit ) block->get_kids().push_back( listInit ); 142 136 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 143 137 … … 146 140 147 141 template< typename OutputIterator > 148 voidgenCall( 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 ) { 149 143 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 150 144 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 145 return 0; 151 146 } else { 152 genScalarCall( srcParam, dstParam, fname, out, type, addCast );147 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 153 148 } 154 149 } … … 171 166 // 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 172 167 assert( stmts.size() <= 1 ); 173 174 175 176 177 178 179 180 181 182 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 } 184 179 } 185 180 } // namespace SymTab -
src/SynTree/Declaration.cc
r73bf8cf2 rf9cebb5 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Declaration.cc -- 7 // Declaration.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 20 20 #include "Initializer.h" 21 21 #include "Type.h" 22 #include "Attribute.h" 22 23 #include "Common/utility.h" 23 24 -
src/SynTree/Declaration.h
r73bf8cf2 rf9cebb5 64 64 class DeclarationWithType : public Declaration { 65 65 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 ); 67 67 DeclarationWithType( const DeclarationWithType &other ); 68 68 virtual ~DeclarationWithType(); … … 75 75 int get_scopeLevel() const { return scopeLevel; } 76 76 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; } 77 80 78 81 virtual DeclarationWithType *clone() const = 0; … … 87 90 // shadowed identifiers can be accessed 88 91 int scopeLevel = 0; 92 93 std::list< Attribute * > attributes; 89 94 }; 90 95 … … 92 97 typedef DeclarationWithType Parent; 93 98 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 ); 95 100 ObjectDecl( const ObjectDecl &other ); 96 101 virtual ~ObjectDecl(); … … 131 136 std::list< std::string >& get_oldIdents() { return oldIdents; } 132 137 std::list< Declaration* >& get_oldDecls() { return oldDecls; } 133 std::list< Attribute * >& get_attributes() { return attributes; }134 138 135 139 virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); } … … 143 147 std::list< std::string > oldIdents; 144 148 std::list< Declaration* > oldDecls; 145 std::list< Attribute * > attributes;146 149 }; 147 150 -
src/SynTree/DeclarationWithType.cc
r73bf8cf2 rf9cebb5 16 16 #include "Declaration.h" 17 17 #include "Type.h" 18 #include "Attribute.h" 18 19 #include "Common/utility.h" 19 20 20 DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage )21 : Declaration( name, sc, linkage ) {21 DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, const std::list< Attribute * > & attributes ) 22 : Declaration( name, sc, linkage ), attributes( attributes ) { 22 23 } 23 24 24 25 DeclarationWithType::DeclarationWithType( const DeclarationWithType &other ) 25 26 : Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) { 27 cloneAll( other.attributes, attributes ); 26 28 } 27 29 28 30 DeclarationWithType::~DeclarationWithType() { 31 deleteAll( attributes ); 29 32 } 30 33 -
src/SynTree/FunctionDecl.cc
r73bf8cf2 rf9cebb5 23 23 24 24 FunctionDecl::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 ) { 26 26 set_isInline( isInline ); 27 27 set_isNoreturn( isNoreturn ); … … 34 34 FunctionDecl::FunctionDecl( const FunctionDecl &other ) 35 35 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) { 36 cloneAll( other.attributes, attributes );37 36 } 38 37 … … 40 39 delete type; 41 40 delete statements; 42 deleteAll( attributes );43 41 } 44 42 … … 69 67 } // if 70 68 71 printAll( attributes, os, indent );69 printAll( get_attributes(), os, indent ); 72 70 73 71 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { -
src/SynTree/Label.h
r73bf8cf2 rf9cebb5 24 24 class Label { 25 25 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 ) {} 27 27 Label( const char * name, Statement * labelled = 0 ) : name( name ), labelled( labelled ) {} 28 28 -
src/SynTree/ObjectDecl.cc
r73bf8cf2 rf9cebb5 18 18 #include "Initializer.h" 19 19 #include "Expression.h" 20 #include "Attribute.h" 20 21 #include "Common/utility.h" 21 22 #include "Statement.h" 22 23 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 ) {24 ObjectDecl::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 ) { 25 26 set_isInline( isInline ); 26 27 set_isNoreturn( isNoreturn ); … … 45 46 os << LinkageSpec::toString( get_linkage() ) << " "; 46 47 } // if 48 49 printAll( get_attributes(), os, indent ); 47 50 48 51 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { … … 80 83 } // if 81 84 85 // xxx - should printShort print attributes? 86 82 87 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { 83 88 os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Note: See TracChangeset
for help on using the changeset viewer.