Changes in / [ccb447e:31e46b8]
- Location:
- src
- Files:
-
- 14 edited
-
GenPoly/DeclMutator.h (modified) (2 diffs)
-
InitTweak/FixGlobalInit.cc (modified) (3 diffs)
-
InitTweak/FixInit.cc (modified) (3 diffs)
-
InitTweak/FixInit.h (modified) (1 diff)
-
InitTweak/GenInit.cc (modified) (5 diffs)
-
InitTweak/InitTweak.cc (modified) (2 diffs)
-
InitTweak/InitTweak.h (modified) (1 diff)
-
ResolvExpr/Resolver.cc (modified) (6 diffs)
-
SymTab/Autogen.cc (modified) (3 diffs)
-
SymTab/Autogen.h (modified) (1 diff)
-
SymTab/FixFunction.cc (modified) (2 diffs)
-
SymTab/Validate.cc (modified) (4 diffs)
-
main.cc (modified) (3 diffs)
-
tests/.expect/64/extension.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/DeclMutator.h
rccb447e r31e46b8 28 28 class DeclMutator : public Mutator { 29 29 public: 30 typedef Mutator Parent;31 32 30 DeclMutator(); 33 31 virtual ~DeclMutator(); 34 35 using Parent::mutate; 32 36 33 virtual CompoundStmt* mutate(CompoundStmt *compoundStmt); 37 34 virtual Statement* mutate(IfStmt *ifStmt); … … 45 42 /// Mutates a list of declarations with this visitor 46 43 void mutateDeclarationList(std::list< Declaration* >& decls); 47 44 48 45 /// Called on entry to a new scope; overriders should call this as a super-class call 49 46 virtual void doBeginScope(); -
src/InitTweak/FixGlobalInit.cc
rccb447e r31e46b8 46 46 FunctionDecl * destroyFunction; 47 47 }; 48 49 class ConstExprChecker : public Visitor { 50 public: 51 ConstExprChecker() : isConstExpr( true ) {} 52 53 virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; } 54 virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; } 55 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; } 56 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 57 virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; } 58 virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; } 59 virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; } 60 virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; } 61 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ } 62 // these might be okay? 63 // virtual void visit( SizeofExpr *sizeofExpr ); 64 // virtual void visit( AlignofExpr *alignofExpr ); 65 // virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 66 // virtual void visit( OffsetofExpr *offsetofExpr ); 67 // virtual void visit( OffsetPackExpr *offsetPackExpr ); 68 // virtual void visit( AttrExpr *attrExpr ); 69 // virtual void visit( CommaExpr *commaExpr ); 70 // virtual void visit( LogicalExpr *logicalExpr ); 71 // virtual void visit( ConditionalExpr *conditionalExpr ); 72 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; } 73 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; } 74 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; } 75 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; } 76 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; } 77 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; } 78 79 bool isConstExpr; 80 }; 81 82 bool isConstExpr( Initializer * init ) { 83 if ( init ) { 84 ConstExprChecker checker; 85 init->accept( checker ); 86 return checker.isConstExpr; 87 } // if 88 // for all intents and purposes, no initializer means const expr 89 return true; 90 } 48 91 49 92 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) { … … 97 140 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); 98 141 142 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects 143 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return; 99 144 // C allows you to initialize objects with constant expressions 100 145 // xxx - this is an optimization. Need to first resolve constructors before we decide … … 102 147 // if ( isConstExpr( objDecl->get_init() ) ) return; 103 148 104 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 105 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 106 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 149 if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) { 150 // xxx - initialize each element of the array 151 } else { 152 // steal initializer from object and attach it to a new temporary 153 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() ); 154 objDecl->set_init( NULL ); 155 initStatements.push_back( new DeclStmt( noLabels, newObj ) ); 107 156 108 Statement * dtor = ctorInit->get_dtor(); 109 if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) { 110 // don't need to call intrinsic dtor, because it does nothing, but 111 // non-intrinsic dtors must be called 112 destroyStatements.push_front( dtor ); 113 ctorInit->set_dtor( NULL ); 114 } // if 115 if ( Statement * ctor = ctorInit->get_ctor() ) { 116 initStatements.push_back( ctor ); 117 objDecl->set_init( NULL ); 118 ctorInit->set_ctor( NULL ); 119 } else if ( Initializer * init = ctorInit->get_init() ) { 120 objDecl->set_init( init ); 121 ctorInit->set_init( NULL ); 122 } else { 123 // no constructor and no initializer, which is okay 124 objDecl->set_init( NULL ); 125 } // if 126 delete ctorInit; 157 // copy construct objDecl using temporary 158 UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) ); 159 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 160 init->get_args().push_back( new VariableExpr( newObj ) ); 161 initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) ); 162 163 // add destructor calls to global destroy function 164 UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) ); 165 destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 166 destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) ); 127 167 } // if 128 168 } -
src/InitTweak/FixInit.cc
rccb447e r31e46b8 18 18 #include <iterator> 19 19 #include <algorithm> 20 #include "FixInit.h" 20 21 #include "InitTweak.h" 21 #include "FixInit.h"22 #include "FixGlobalInit.h"23 22 #include "ResolvExpr/Resolver.h" 24 23 #include "ResolvExpr/typeops.h" … … 84 83 }; 85 84 86 // debug87 85 struct printSet { 88 86 typedef ObjDeclCollector::ObjectSet ObjectSet; … … 173 171 } // namespace 174 172 175 void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) { 176 // fixes ConstructorInit for global variables. should happen before fixInitializers. 177 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 178 173 void fix( std::list< Declaration * > & translationUnit ) { 179 174 InsertImplicitCalls::insert( translationUnit ); 180 175 ResolveCopyCtors::resolveImplicitCalls( translationUnit ); -
src/InitTweak/FixInit.h
rccb447e r31e46b8 27 27 /// replace constructor initializers with expression statements 28 28 /// and unwrap basic C-style initializers 29 void fix( std::list< Declaration * > & translationUnit , const std::string & name, bool inLibrary);29 void fix( std::list< Declaration * > & translationUnit ); 30 30 } // namespace 31 31 -
src/InitTweak/GenInit.cc
rccb447e r31e46b8 26 26 #include "SymTab/Autogen.h" 27 27 #include "GenPoly/PolyMutator.h" 28 #include "GenPoly/DeclMutator.h"29 28 30 29 namespace InitTweak { … … 56 55 public: 57 56 /// create constructor and destructor statements for object declarations. 58 /// the actual call statements will be added in after the resolver has run59 /// so that the initializer expression is only removed if a constructor is found60 /// and the same destructor call is inserted in all of the appropriate locations.57 /// Destructors are inserted directly into the code, whereas constructors 58 /// will be added in after the resolver has run so that the initializer expression 59 /// is only removed if a constructor is found 61 60 static void generateCtorDtor( std::list< Declaration * > &translationUnit ); 61 62 CtorDtor() : inFunction( false ) {} 62 63 63 64 virtual DeclarationWithType * mutate( ObjectDecl * ); 64 65 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 65 // should not traverse into any of these declarations to find objects 66 // that need to be constructed or destructed 67 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; } 68 virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; } 69 virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; } 70 virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; } 71 virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; } 72 virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; } 73 74 virtual Type * mutate( FunctionType *funcType ) { return funcType; } 66 virtual Declaration* mutate( StructDecl *aggregateDecl ); 67 virtual Declaration* mutate( UnionDecl *aggregateDecl ); 68 virtual Declaration* mutate( EnumDecl *aggregateDecl ); 69 virtual Declaration* mutate( TraitDecl *aggregateDecl ); 70 virtual TypeDecl* mutate( TypeDecl *typeDecl ); 71 virtual Declaration* mutate( TypedefDecl *typeDecl ); 72 73 virtual Type * mutate( FunctionType *funcType ); 75 74 76 75 protected: 77 }; 78 79 class HoistArrayDimension : public GenPoly::DeclMutator { 80 public: 81 typedef GenPoly::DeclMutator Parent; 82 83 /// hoist dimension from array types in object declaration so that it uses a single 84 /// const variable of type size_t, so that side effecting array dimensions are only 85 /// computed once. 86 static void hoistArrayDimension( std::list< Declaration * > & translationUnit ); 87 88 private: 89 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ); 90 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 91 // should not traverse into any of these declarations to find objects 92 // that need to be constructed or destructed 93 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; } 94 virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; } 95 virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; } 96 virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; } 97 virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; } 98 virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; } 99 100 virtual Type* mutate( FunctionType *funcType ) { return funcType; } 101 102 void hoist( Type * type ); 103 104 DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass; 105 bool inFunction = false; 76 bool inFunction; 106 77 }; 107 78 108 79 void genInit( std::list< Declaration * > & translationUnit ) { 109 80 ReturnFixer::makeReturnTemp( translationUnit ); 110 HoistArrayDimension::hoistArrayDimension( translationUnit );111 81 CtorDtor::generateCtorDtor( translationUnit ); 112 82 } … … 154 124 } 155 125 156 void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {157 HoistArrayDimension hoister;158 hoister.mutateDeclarationList( translationUnit );159 }160 161 DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {162 storageclass = objectDecl->get_storageClass();163 DeclarationWithType * temp = Parent::mutate( objectDecl );164 hoist( objectDecl->get_type() );165 storageclass = DeclarationNode::NoStorageClass;166 return temp;167 }168 169 void HoistArrayDimension::hoist( Type * type ) {170 // if in function, generate const size_t var171 static UniqueName dimensionName( "_array_dim" );172 if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {173 if ( ! inFunction ) return;174 175 if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?176 177 // don't need to hoist dimension if it's a constexpr - only need to if there's potential178 // for side effects.179 if ( isConstExpr( arrayType->get_dimension() ) ) return;180 181 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageclass, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );182 arrayDimension->get_type()->set_isConst( true );183 184 arrayType->set_dimension( new VariableExpr( arrayDimension ) );185 addDeclaration( arrayDimension );186 187 hoist( arrayType->get_base() );188 return;189 }190 }191 192 DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {193 bool oldInFunc = inFunction;194 inFunction = true;195 DeclarationWithType * decl = Parent::mutate( functionDecl );196 inFunction = oldInFunc;197 return decl;198 }199 126 200 127 void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) { … … 213 140 214 141 DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) { 215 // hands off if designated , if @=, or if extern142 // hands off if designated or if @= 216 143 if ( tryConstruct( objDecl ) ) { 217 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 218 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 219 // TODO: walk initializers and generate appropriate ctor if element has initializer. 220 // Initializer could be nested (depends on the depth of the array type on the object) 221 222 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 223 if ( args.empty() ) { 224 std::list< Statement * > ctor; 225 std::list< Statement * > dtor; 226 227 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 228 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 229 230 // Currently genImplicitCall produces a single Statement - a CompoundStmt 231 // which wraps everything that needs to happen. As such, it's technically 232 // possible to use a Statement ** in the above calls, but this is inherently 233 // unsafe, so instead we take the slightly less efficient route, but will be 234 // immediately informed if somehow the above assumption is broken. In this case, 235 // we could always wrap the list of statements at this point with a CompoundStmt, 236 // but it seems reasonable at the moment for this to be done by genImplicitCall 237 // itself. It is possible that genImplicitCall produces no statements (e.g. if 238 // an array type does not have a dimension). In this case, it's fine to ignore 239 // the object for the purposes of construction. 240 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 241 if ( ctor.size() == 1 ) { 242 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 144 if ( inFunction ) { 145 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 146 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 147 // TODO: walk initializer and generate appropriate copy ctor if element has initializer 148 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 149 if ( args.empty() ) { 150 std::list< Statement * > ctor; 151 std::list< Statement * > dtor; 152 153 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) ); 154 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false ); 155 156 // Currently makeArrayFunction produces a single Statement - a CompoundStmt 157 // which wraps everything that needs to happen. As such, it's technically 158 // possible to use a Statement ** in the above calls, but this is inherently 159 // unsafe, so instead we take the slightly less efficient route, but will be 160 // immediately informed if somehow the above assumption is broken. In this case, 161 // we could always wrap the list of statements at this point with a CompoundStmt, 162 // but it seems reasonable at the moment for this to be done by makeArrayFunction 163 // itself 164 assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) ); 165 assert( dtor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( dtor.front() ) ); 243 166 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 167 } else { 168 // array came with an initializer list: initialize each element 169 // may have more initializers than elements in the array - need to check at each index that 170 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 171 // computation. 172 // may have fewer initializers than eleemnts in the array - need to default construct 173 // remaining elements. 174 // might be able to merge this with the case above. 244 175 } 245 176 } else { 246 // array came with an initializer list: initialize each element 247 // may have more initializers than elements in the array - need to check at each index that 248 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 249 // computation. 250 // may have fewer initializers than elements in the array - need to default construct 251 // remaining elements. 252 // might be able to merge this with the case above. 253 177 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer 178 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) ); 179 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() ); 180 181 // need to remember init expression, in case no ctors exist 182 // if ctor does exist, want to use ctor expression instead of init 183 // push this decision to the resolver 184 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor ); 185 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor ); 186 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) ); 254 187 } 255 } else {256 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer257 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );258 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );259 260 // need to remember init expression, in case no ctors exist261 // if ctor does exist, want to use ctor expression instead of init262 // push this decision to the resolver263 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );264 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );265 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );266 188 } 267 189 } … … 271 193 DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) { 272 194 // parameters should not be constructed and destructed, so don't mutate FunctionType 195 bool oldInFunc = inFunction; 273 196 mutateAll( functionDecl->get_oldDecls(), *this ); 197 inFunction = true; 274 198 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 199 inFunction = oldInFunc; 275 200 return functionDecl; 276 201 } 202 203 // should not traverse into any of these declarations to find objects 204 // that need to be constructed or destructed 205 Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; } 206 Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; } 207 Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; } 208 Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; } 209 TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; } 210 Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; } 211 Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; } 212 277 213 } // namespace InitTweak 278 214 -
src/InitTweak/InitTweak.cc
rccb447e r31e46b8 57 57 (objDecl->get_init() == NULL || 58 58 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) && 59 ! isDesignated( objDecl->get_init() ) 60 && objDecl->get_storageClass() != DeclarationNode::Extern; 59 ! isDesignated( objDecl->get_init() ); 61 60 } 62 61 … … 161 160 else return NULL; 162 161 } 163 164 class ConstExprChecker : public Visitor {165 public:166 ConstExprChecker() : isConstExpr( true ) {}167 168 virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }169 virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }170 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }171 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }172 virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }173 virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }174 virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }175 virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }176 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }177 // these might be okay?178 // virtual void visit( SizeofExpr *sizeofExpr );179 // virtual void visit( AlignofExpr *alignofExpr );180 // virtual void visit( UntypedOffsetofExpr *offsetofExpr );181 // virtual void visit( OffsetofExpr *offsetofExpr );182 // virtual void visit( OffsetPackExpr *offsetPackExpr );183 // virtual void visit( AttrExpr *attrExpr );184 // virtual void visit( CommaExpr *commaExpr );185 // virtual void visit( LogicalExpr *logicalExpr );186 // virtual void visit( ConditionalExpr *conditionalExpr );187 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }188 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }189 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }190 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }191 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }192 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }193 194 bool isConstExpr;195 };196 197 bool isConstExpr( Expression * expr ) {198 if ( expr ) {199 ConstExprChecker checker;200 expr->accept( checker );201 return checker.isConstExpr;202 }203 return true;204 }205 206 bool isConstExpr( Initializer * init ) {207 if ( init ) {208 ConstExprChecker checker;209 init->accept( checker );210 return checker.isConstExpr;211 } // if212 // for all intents and purposes, no initializer means const expr213 return true;214 }215 216 162 } -
src/InitTweak/InitTweak.h
rccb447e r31e46b8 26 26 // helper functions for initialization 27 27 namespace InitTweak { 28 /// transform Initializer into an argument list that can be passed to a call expression29 std::list< Expression * > makeInitList( Initializer * init );28 /// transform Initializer into an argument list that can be passed to a call expression 29 std::list< Expression * > makeInitList( Initializer * init ); 30 30 31 /// True if the resolver should try to construct objDecl32 bool tryConstruct( ObjectDecl * objDecl );31 /// True if the resolver should try to construct objDecl 32 bool tryConstruct( ObjectDecl * objDecl ); 33 33 34 /// True if the Initializer contains designations35 bool isDesignated( Initializer * init );34 /// True if the Initializer contains designations 35 bool isDesignated( Initializer * init ); 36 36 37 /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.38 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.39 /// Currently has assertions that make it less than fully general.40 bool isInstrinsicSingleArgCallStmt( Statement * expr );37 /// True if stmt is a call statement where the function called is intrinsic and takes one parameter. 38 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere. 39 /// Currently has assertions that make it less than fully general. 40 bool isInstrinsicSingleArgCallStmt( Statement * expr ); 41 41 42 /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call43 Expression * getCtorDtorCall( Statement * stmt );42 /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call 43 Expression * getCtorDtorCall( Statement * stmt ); 44 44 45 /// returns the name of the function being called46 std::string getFunctionName( Expression * expr );45 /// returns the name of the function being called 46 std::string getFunctionName( Expression * expr ); 47 47 48 /// returns the argument to a call expression in position N indexed from 049 Expression *& getCallArg( Expression * callExpr, unsigned int pos );48 /// returns the argument to a call expression in position N indexed from 0 49 Expression *& getCallArg( Expression * callExpr, unsigned int pos ); 50 50 51 /// returns the base type of a PointerType or ArrayType, else returns NULL52 Type * getPointerBase( Type * );51 /// returns the base type of a PointerType or ArrayType, else returns NULL 52 Type * getPointerBase( Type * ); 53 53 54 /// returns the argument if it is a PointerType or ArrayType, else returns NULL 55 Type * isPointerType( Type * ); 56 57 /// returns true if expr is trivially a compile-time constant 58 bool isConstExpr( Expression * expr ); 59 bool isConstExpr( Initializer * init ); 54 /// returns the argument if it is a PointerType or ArrayType, else returns NULL 55 Type * isPointerType( Type * ); 60 56 } // namespace 61 57 -
src/ResolvExpr/Resolver.cc
rccb447e r31e46b8 24 24 #include "SynTree/Initializer.h" 25 25 #include "SymTab/Indexer.h" 26 #include "SymTab/Autogen.h"27 26 #include "Common/utility.h" 28 27 #include "InitTweak/InitTweak.h" … … 42 41 43 42 virtual void visit( ArrayType * at ); 44 virtual void visit( PointerType * at );45 43 46 44 virtual void visit( ExprStmt *exprStmt ); … … 61 59 private: 62 60 typedef std::list< Initializer * >::iterator InitIterator; 63 64 template< typename PtrType >65 void handlePtrType( PtrType * type );66 61 67 62 void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & ); … … 197 192 } 198 193 199 template< typename PtrType >200 void Resolver::handlePtrType( PtrType * type) {201 if ( type->get_dimension() ) {202 CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );194 void Resolver::visit( ArrayType * at ) { 195 if ( at->get_dimension() ) { 196 BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 197 CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() ); 203 198 Expression *newExpr = findSingleExpression( castExpr, *this ); 204 delete type->get_dimension(); 205 type->set_dimension( newExpr ); 206 } 207 } 208 209 void Resolver::visit( ArrayType * at ) { 210 handlePtrType( at ); 199 delete at->get_dimension(); 200 at->set_dimension( newExpr ); 201 } 211 202 Visitor::visit( at ); 212 }213 214 void Resolver::visit( PointerType * pt ) {215 handlePtrType( pt );216 Visitor::visit( pt );217 203 } 218 204 … … 551 537 assert( callExpr ); 552 538 Expression *& constructee = InitTweak::getCallArg( callExpr, 0 ); 553 554 // the first argument will always be &<expr> 555 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee ); 556 assert( addrExpr ); 557 558 // need to find the type of the first argument. In the case of an array, 559 // need to remove one ArrayType layer from the type for each subscript expression. 560 Expression * addressee = addrExpr->get_arg(); 561 int numLayers = 0; 562 while ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( addressee ) ) { 563 assert( InitTweak::getFunctionName( untypedExpr ) == "?[?]" ); 564 addressee = InitTweak::getCallArg( untypedExpr, 0 ); 565 numLayers++; 566 } 567 assert( addressee->get_results().size() == 1 ); 568 Type * type = addressee->get_results().front(); 569 for ( int i = 0; i < numLayers; i++ ) { 570 type = InitTweak::getPointerBase( type ); 571 assert( type && "Expected pointer or array type. May have generated too many ?[?] calls." ); 572 } 573 539 Type * type = 0; 540 541 // need to find the type of the first argument, which is unfortunately not uniform since array construction 542 // includes an untyped '+' expression. 543 if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) { 544 // constructee is <array>+<index> 545 // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed 546 Expression * arr = InitTweak::getCallArg( plusExpr, 0 ); 547 assert( dynamic_cast< VariableExpr * >( arr ) || dynamic_cast< MemberExpr *>( arr ) ); 548 assert( arr && arr->get_results().size() == 1 ); 549 type = arr->get_results().front()->clone(); 550 } else { 551 // otherwise, constructing a plain object, which means the object's address is being taken. 552 // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the 553 // type of the VariableExpr to do so. 554 assert( constructee->get_results().size() == 1 ); 555 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee ); 556 assert( addrExpr && addrExpr->get_results().size() == 1 ); 557 type = addrExpr->get_results().front()->clone(); 558 } 574 559 // cast to T* with qualifiers removed. 575 560 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument … … 577 562 // remove lvalue as a qualifier, this can change to 578 563 // type->get_qualifiers() = Type::Qualifiers(); 579 assert( type ); 580 type = type->clone(); 581 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 582 type = new PointerType( Type::Qualifiers(), type ); 564 Type * base = InitTweak::getPointerBase( type ); 565 assert( base ); 566 base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 567 // if pointer has lvalue qualifier, cast won't appear in output 568 type->set_isLvalue( false ); 583 569 constructee = new CastExpr( constructee, type ); 584 570 -
src/SymTab/Autogen.cc
rccb447e r31e46b8 26 26 27 27 namespace SymTab { 28 Type * SizeType = 0;29 30 28 class AutogenerateRoutines : public Visitor { 31 29 public: … … 61 59 bool isUnnamedBitfield( ObjectDecl * obj ) { 62 60 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL; 61 } 62 63 template< typename OutputIterator > 64 void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) { 65 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); 66 // unnamed bit fields are not copied as they cannot be accessed 67 if ( isUnnamedBitfield( obj ) ) return; 68 69 // want to be able to generate assignment, ctor, and dtor generically, 70 // so fname is either ?=?, ?{}, or ^?{} 71 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 72 73 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 74 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 75 76 // do something special for unnamed members 77 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 78 fExpr->get_args().push_back( dstselect ); 79 80 if ( src ) { 81 fExpr->get_args().push_back( src ); 82 } 83 84 Statement * callStmt = new ExprStmt( noLabels, fExpr ); 85 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) { 86 // implicitly generated ctor/dtor calls should be wrapped 87 // so that later passes are aware they were generated. 88 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 89 // because this causes the address to be taken at codegen, which is illegal in C. 90 callStmt = new ImplicitCtorDtorStmt( callStmt ); 91 } 92 *out++ = callStmt; 63 93 } 64 94 … … 190 220 191 221 // assign to destination (and return value if generic) 192 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 193 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 194 Expression *dstselect = new MemberExpr( field, derefExpr ); 195 genImplicitCall( src, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 196 197 if ( isGeneric && returnVal ) { 198 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 199 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 200 Expression *retselect = new MemberExpr( field, derefRet ); 201 genImplicitCall( src, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 222 if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) { 223 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 224 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 225 Expression *dstselect = new MemberExpr( field, derefExpr ); 226 227 makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 228 if ( isGeneric && returnVal ) { 229 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 230 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 231 Expression *retselect = new MemberExpr( field, derefRet ); 232 233 makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 234 } 235 } else { 236 makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 237 if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 202 238 } // if 203 239 } -
src/SymTab/Autogen.h
rccb447e r31e46b8 24 24 25 25 namespace SymTab { 26 /// Generates assignment operators, constructors, and destructor for aggregate types as required27 void autogenerateRoutines( std::list< Declaration * > &translationUnit );26 /// Generates assignment operators, constructors, and destructor for aggregate types as required 27 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 28 28 29 /// returns true if obj's name is the empty string and it has a bitfield width 30 bool isUnnamedBitfield( ObjectDecl * obj ); 29 // originally makeArrayAssignment - changed to Function because it is now used for ctors and dtors as well 30 // admittedly not a great name change. This used to live in Validate.cc, but has been moved so it can be reused elsewhere 31 31 32 /// size_t type - set when size_t typedef is seen. Useful in a few places, 33 /// such as in determining array dimension type 34 extern Type * SizeType; 32 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 33 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 34 template< typename OutputIterator > 35 void makeArrayFunction( Expression *srcParam, Expression *dstParam, ArrayType *array, std::string fname, OutputIterator out, bool forward = true ) { 36 static UniqueName indexName( "_index" ); 35 37 36 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 37 template< typename OutputIterator > 38 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true ); 38 // for a flexible array member nothing is done -- user must define own assignment 39 if ( ! array->get_dimension() ) return; 39 40 40 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 41 template< typename OutputIterator > 42 void genScalarCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) { 43 // want to be able to generate assignment, ctor, and dtor generically, 44 // so fname is either ?=?, ?{}, or ^?{} 45 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 41 Expression * begin, * end, * update, * cmp; 42 if ( forward ) { 43 // generate: for ( int i = 0; i < 0; ++i ) 44 begin = new NameExpr( "0" ); 45 end = array->get_dimension()->clone(); 46 cmp = new NameExpr( "?<?" ); 47 update = new NameExpr( "++?" ); 48 } else { 49 // generate: for ( int i = N-1; i >= 0; --i ) 50 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 51 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 52 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 53 end = new NameExpr( "0" ); 54 cmp = new NameExpr( "?>=?" ); 55 update = new NameExpr( "--?" ); 56 } 46 57 47 // do something special for unnamed members 48 fExpr->get_args().push_back( new AddressExpr( dstParam ) ); 58 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 49 59 50 if ( srcParam ) { 51 fExpr->get_args().push_back( srcParam ); 52 } 60 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 61 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 62 init->get_args().push_back( begin ); 63 index->set_init( new SingleInit( init, std::list<Expression*>() ) ); 53 64 54 *out++ = new ExprStmt( noLabels, fExpr ); 55 } 65 UntypedExpr *cond = new UntypedExpr( cmp ); 66 cond->get_args().push_back( new VariableExpr( index ) ); 67 cond->get_args().push_back( end ); 56 68 57 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 58 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 59 template< typename OutputIterator > 60 void genArrayCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) { 61 static UniqueName indexName( "_index" ); 69 UntypedExpr *inc = new UntypedExpr( update ); 70 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 62 71 63 // for a flexible array member nothing is done -- user must define own assignment 64 if ( ! array->get_dimension() ) return ; 72 // want to be able to generate assignment, ctor, and dtor generically, 73 // so fname is either ?=?, ?{}, or ^?{} 74 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 65 75 66 Expression * begin, * end, * update, * cmp; 67 if ( forward ) { 68 // generate: for ( int i = 0; i < 0; ++i ) 69 begin = new NameExpr( "0" ); 70 end = array->get_dimension()->clone(); 71 cmp = new NameExpr( "?<?" ); 72 update = new NameExpr( "++?" ); 73 } else { 74 // generate: for ( int i = N-1; i >= 0; --i ) 75 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 76 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 77 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 78 end = new NameExpr( "0" ); 79 cmp = new NameExpr( "?>=?" ); 80 update = new NameExpr( "--?" ); 81 } 76 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); 77 dstIndex->get_args().push_back( dstParam ); 78 dstIndex->get_args().push_back( new VariableExpr( index ) ); 79 fExpr->get_args().push_back( dstIndex ); 82 80 83 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 81 // srcParam is NULL for default ctor/dtor 82 if ( srcParam ) { 83 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 84 srcIndex->get_args().push_back( srcParam ); 85 srcIndex->get_args().push_back( new VariableExpr( index ) ); 86 fExpr->get_args().push_back( srcIndex ); 87 } 84 88 85 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );86 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ));87 init->get_args().push_back( begin);88 index->set_init( new SingleInit( init, std::list<Expression*>() ) );89 std::list<Statement *> initList; 90 CompoundStmt * block = new CompoundStmt( noLabels ); 91 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 92 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) ) ); 89 93 90 UntypedExpr *cond = new UntypedExpr( cmp ); 91 cond->get_args().push_back( new VariableExpr( index ) ); 92 cond->get_args().push_back( end ); 93 94 UntypedExpr *inc = new UntypedExpr( update ); 95 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 96 97 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 98 dstIndex->get_args().push_back( dstParam ); 99 dstIndex->get_args().push_back( new VariableExpr( index ) ); 100 dstParam = dstIndex; 101 102 // srcParam is NULL for default ctor/dtor 103 if ( srcParam ) { 104 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 105 srcIndex->get_args().push_back( srcParam ); 106 srcIndex->get_args().push_back( new VariableExpr( index ) ); 107 srcParam = srcIndex; 108 } 109 110 // for stmt's body, eventually containing call 111 CompoundStmt * body = new CompoundStmt( noLabels ); 112 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward ); 113 114 // block containing for stmt and index variable 115 std::list<Statement *> initList; 116 CompoundStmt * block = new CompoundStmt( noLabels ); 117 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 118 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 119 120 *out++ = block; 121 } 122 123 template< typename OutputIterator > 124 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) { 125 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 126 genArrayCall( srcParam, dstParam, fname, out, at, forward ); 127 } else { 128 genScalarCall( srcParam, dstParam, fname, out ); 129 } 130 } 131 132 /// inserts into out a generated call expression to function fname with arguments dstParam 133 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 134 /// object being constructed. The function wraps constructor and destructor calls in an 135 /// ImplicitCtorDtorStmt node. 136 template< typename OutputIterator > 137 void genImplicitCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 138 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 139 assert( obj ); 140 // unnamed bit fields are not copied as they cannot be accessed 141 if ( isUnnamedBitfield( obj ) ) return; 142 143 std::list< Statement * > stmts; 144 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward ); 145 146 // 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 147 assert( stmts.size() <= 1 ); 148 if ( stmts.size() == 1 ) { 149 Statement * callStmt = stmts.front(); 150 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) { 151 // implicitly generated ctor/dtor calls should be wrapped 152 // so that later passes are aware they were generated. 153 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 154 // because this causes the address to be taken at codegen, which is illegal in C. 155 callStmt = new ImplicitCtorDtorStmt( callStmt ); 156 } 157 *out++ = callStmt; 94 Statement * stmt = block; 95 if ( fname == "?{}" || fname == "^?{}" ) { 96 // implicitly generated ctor/dtor calls should be wrapped 97 // so that later passes are aware they were generated 98 stmt = new ImplicitCtorDtorStmt( stmt ); 158 99 } 159 } 100 *out++ = stmt; 101 } 160 102 } // namespace SymTab 161 103 #endif // AUTOGEN_H -
src/SymTab/FixFunction.cc
rccb447e r31e46b8 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixFunction.cc -- 7 // FixFunction.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 44 44 45 45 Type * FixFunction::mutate(ArrayType *arrayType) { 46 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 47 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 46 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 48 47 delete arrayType; 49 48 return pointerType; -
src/SymTab/Validate.cc
rccb447e r31e46b8 174 174 175 175 virtual void visit( FunctionDecl *funcDecl ); 176 };176 }; 177 177 178 178 class CompoundLiteral : public GenPoly::DeclMutator { … … 191 191 EliminateTypedef::eliminateTypedef( translationUnit ); 192 192 HoistStruct::hoistStruct( translationUnit ); 193 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1194 193 acceptAll( translationUnit, pass1 ); 195 194 acceptAll( translationUnit, pass2 ); 196 195 ReturnChecker::checkFunctionReturns( translationUnit ); 197 compoundliteral.mutateDeclarationList( translationUnit ); 196 mutateAll( translationUnit, compoundliteral ); 197 autogenerateRoutines( translationUnit ); 198 198 acceptAll( translationUnit, pass3 ); 199 199 VerifyCtorDtor::verify( translationUnit ); … … 490 490 EliminateTypedef eliminator; 491 491 mutateAll( translationUnit, eliminator ); 492 if ( eliminator.typedefNames.count( "size_t" ) ) {493 // grab and remember declaration of size_t494 SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();495 } else {496 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong497 // eventually should have a warning for this case.498 SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );499 }500 492 filter( translationUnit, isTypedef, true ); 501 502 493 } 503 494 … … 527 518 Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) { 528 519 Declaration *ret = Mutator::mutate( tyDecl ); 529 530 520 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 531 521 // typedef to the same name from the same scope -
src/main.cc
rccb447e r31e46b8 42 42 #include "InitTweak/GenInit.h" 43 43 #include "InitTweak/FixInit.h" 44 #include "InitTweak/FixGlobalInit.h" 44 45 //#include "Explain/GenProlog.h" 45 46 //#include "Try/Visit.h" … … 281 282 OPTPRINT( "fixNames" ) 282 283 CodeGen::fixNames( translationUnit ); 284 OPTPRINT( "fixGlobalInit" ); 285 InitTweak::fixGlobalInit( translationUnit, filename, libcfap || treep ); 283 286 OPTPRINT( "tweakInit" ) 284 287 InitTweak::genInit( translationUnit ); … … 301 304 } 302 305 306 OPTPRINT( "fixInit" ) 303 307 // fix ObjectDecl - replaces ConstructorInit nodes 304 OPTPRINT( "fixInit" ) 305 InitTweak::fix( translationUnit, filename, libcfap || treep ); 308 InitTweak::fix( translationUnit ); 306 309 if ( ctorinitp ) { 307 310 dump ( translationUnit ); -
src/tests/.expect/64/extension.txt
rccb447e r31e46b8 100 100 ((void)((__extension__ __a__i_2 , __extension__ __b__i_2) , __extension__ __c__i_2)); 101 101 } 102 __attribute__ ((constructor(),)) static void _init_extension(void){ 103 int _global_init0; 104 ((void)((*((int *)(&__a__i_1)))=_global_init0) /* ?{} */); 105 int _global_init1; 106 ((void)((*((int *)(&__b__i_1)))=_global_init1) /* ?{} */); 107 int _global_init2; 108 ((void)((*((int *)(&__c__i_1)))=_global_init2) /* ?{} */); 109 } 110 __attribute__ ((destructor(),)) static void _destroy_extension(void){ 111 ((void)((*((int *)(&__c__i_1)))) /* ^?{} */); 112 ((void)((*((int *)(&__b__i_1)))) /* ^?{} */); 113 ((void)((*((int *)(&__a__i_1)))) /* ^?{} */); 114 }
Note:
See TracChangeset
for help on using the changeset viewer.