Changeset ae357ec
- Timestamp:
- Mar 8, 2016, 10:25:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 5447e09
- Parents:
- b63e376 (diff), bed4c63e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 8 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rb63e376 rae357ec 21 21 #include "Parser/ParseNode.h" 22 22 23 #include "SynTree/ Type.h"23 #include "SynTree/Declaration.h" 24 24 #include "SynTree/Expression.h" 25 25 #include "SynTree/Initializer.h" 26 26 #include "SynTree/Statement.h" 27 #include "SynTree/Type.h" 27 28 28 29 #include "Common/utility.h" -
src/CodeGen/CodeGenerator.h
rb63e376 rae357ec 19 19 #include <list> 20 20 21 #include "SynTree/Declaration.h" 21 22 #include "SynTree/SynTree.h" 22 23 #include "SynTree/Visitor.h" 24 23 25 #include "SymTab/Indexer.h" 24 26 -
src/CodeGen/GenType.cc
rb63e376 rae357ec 19 19 #include "GenType.h" 20 20 #include "CodeGenerator.h" 21 22 #include "SynTree/Declaration.h" 23 #include "SynTree/Expression.h" 24 #include "SynTree/Type.h" 21 25 #include "SynTree/Visitor.h" 22 #include "SynTree/Type.h"23 #include "SynTree/Expression.h"24 26 25 27 namespace CodeGen { -
src/GenPoly/Box.cc
rb63e376 rae357ec 14 14 // 15 15 16 #include <algorithm> 17 #include <iterator> 18 #include <list> 19 #include <map> 16 20 #include <set> 17 21 #include <stack> 18 22 #include <string> 19 #include < iterator>20 #include < algorithm>23 #include <utility> 24 #include <vector> 21 25 #include <cassert> 22 26 23 27 #include "Box.h" 24 #include " InstantiateGeneric.h"28 #include "DeclMutator.h" 25 29 #include "PolyMutator.h" 26 30 #include "FindFunction.h" 31 #include "ScopedMap.h" 27 32 #include "ScrubTyVars.h" 28 33 … … 30 35 31 36 #include "SynTree/Constant.h" 32 #include "SynTree/ Type.h"37 #include "SynTree/Declaration.h" 33 38 #include "SynTree/Expression.h" 34 39 #include "SynTree/Initializer.h" 40 #include "SynTree/Mutator.h" 35 41 #include "SynTree/Statement.h" 36 #include "SynTree/Mutator.h" 42 #include "SynTree/Type.h" 43 #include "SynTree/TypeSubstitution.h" 37 44 38 45 #include "ResolvExpr/TypeEnvironment.h" … … 40 47 #include "ResolvExpr/typeops.h" 41 48 49 #include "SymTab/Indexer.h" 42 50 #include "SymTab/Mangler.h" 43 51 … … 54 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 55 63 64 /// Key for a unique concrete type; generic base type paired with type parameter list 65 struct ConcreteType { 66 ConcreteType() : base(NULL), params() {} 67 68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 69 70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 71 72 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 params.push_back( (*param)->get_type()->clone() ); 76 } 77 } 78 79 ConcreteType& operator= (const ConcreteType& that) { 80 deleteAll( params ); 81 params.clear(); 82 83 base = that.base; 84 cloneAll( that.params, params ); 85 86 return *this; 87 } 88 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 93 94 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false; 96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; 98 } 99 return true; 100 } 101 102 AggregateDecl *base; ///< Base generic type 103 std::list< Type* > params; ///< Instantiation parameters 104 }; 105 106 /// Maps a concrete type to the some value, accounting for scope 107 template< typename Value > 108 class InstantiationMap { 109 /// Information about a specific instantiation of a generic type 110 struct Instantiation { 111 ConcreteType key; ///< Instantiation parameters for this type 112 Value *value; ///< Value for this instantiation 113 114 Instantiation() : key(), value(0) {} 115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {} 116 }; 117 /// Map of generic types to instantiations of them 118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 121 122 public: 123 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 128 129 /// Ends a scope 130 void endScope() { 131 scopes.pop_back(); 132 } 133 134 /// Default constructor initializes with one scope 135 InstantiationMap() { beginScope(); } 136 137 // private: 138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 139 /// Returns NULL on none such. 140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 141 ConcreteType key(generic, params); 142 // scan scopes from innermost out 143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 144 // skip scope if no instantiations of this generic type 145 typename Scope::const_iterator insts = scope->find( generic ); 146 if ( insts == scope->end() ) continue; 147 // look through instantiations for matches to concrete type 148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 149 if ( inst->key == key ) return inst->value; 150 } 151 } 152 // no matching instantiation found 153 return 0; 154 } 155 public: 156 // StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 157 // UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 158 159 // private: 160 /// Adds a value for a concrete type to the current scope 161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, Value *value ) { 162 ConcreteType key(generic, params); 163 scopes.back()[generic].push_back( Instantiation( key, value ) ); 164 } 165 // public: 166 // void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 167 // void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 168 }; 169 170 /// Adds layout-generation functions to polymorphic types 171 class LayoutFunctionBuilder : public DeclMutator { 172 unsigned int functionNesting; // current level of nested functions 173 public: 174 LayoutFunctionBuilder() : functionNesting( 0 ) {} 175 176 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 177 virtual Declaration *mutate( StructDecl *structDecl ); 178 virtual Declaration *mutate( UnionDecl *unionDecl ); 179 }; 180 56 181 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 57 182 class Pass1 : public PolyMutator { … … 100 225 ObjectDecl *makeTemporary( Type *type ); 101 226 102 typedef std::map< std::string, DeclarationWithType *> AdapterMap;103 227 std::map< std::string, DeclarationWithType *> assignOps; 104 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 105 std::stack< AdapterMap> adapters;229 ScopedMap< std::string, DeclarationWithType* > adapters; 106 230 DeclarationWithType *retval; 107 231 bool useRetval; … … 124 248 125 249 std::map< UniqueId, std::string > adapterName; 250 }; 251 252 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 253 class GenericInstantiator : public DeclMutator { 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations; 256 /// Namer for concrete types 257 UniqueName typeNamer; 258 259 public: 260 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 261 262 virtual Type* mutate( StructInstType *inst ); 263 virtual Type* mutate( UnionInstType *inst ); 264 265 // virtual Expression* mutate( MemberExpr *memberExpr ); 266 267 virtual void doBeginScope(); 268 virtual void doEndScope(); 269 private: 270 /// Wrap instantiation lookup for structs 271 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); } 272 /// Wrap instantiation lookup for unions 273 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); } 274 /// Wrap instantiation insertion for structs 275 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); } 276 /// Wrap instantiation insertion for unions 277 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 126 278 }; 127 279 … … 159 311 } // anonymous namespace 160 312 161 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {162 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {163 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {164 (*i)->print( os );165 os << std::endl;166 } // if167 } // for168 }169 170 313 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 171 314 template< typename MutatorType > … … 195 338 196 339 void box( std::list< Declaration *>& translationUnit ) { 340 LayoutFunctionBuilder layoutBuilder; 197 341 Pass1 pass1; 198 342 Pass2 pass2; 343 GenericInstantiator instantiator; 199 344 MemberExprFixer memberFixer; 200 345 Pass3 pass3; 346 347 layoutBuilder.mutateDeclarationList( translationUnit ); 201 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 202 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 203 instantiateGeneric( translationUnit ); 350 // instantiateGeneric( translationUnit ); 351 instantiator.mutateDeclarationList( translationUnit ); 204 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 205 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 206 354 } 207 355 356 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 357 358 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) { 359 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 360 mutateAll( functionDecl->get_oldDecls(), *this ); 361 ++functionNesting; 362 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 363 --functionNesting; 364 return functionDecl; 365 } 366 367 /// Get a list of type declarations that will affect a layout function 368 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { 369 std::list< TypeDecl * > otypeDecls; 370 371 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 372 if ( (*decl)->get_kind() == TypeDecl::Any ) { 373 otypeDecls.push_back( *decl ); 374 } 375 } 376 377 return otypeDecls; 378 } 379 380 /// Adds parameters for otype layout to a function type 381 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 382 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 383 384 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 385 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 386 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 388 } 389 } 390 391 /// Builds a layout function declaration 392 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) { 393 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 394 // because each unit generates copies of the default routines for each aggregate. 395 FunctionDecl *layoutDecl = new FunctionDecl( 396 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false ); 397 layoutDecl->fixUniqueId(); 398 return layoutDecl; 399 } 400 401 /// Makes a unary operation 402 Expression *makeOp( const std::string &name, Expression *arg ) { 403 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 404 expr->get_args().push_back( arg ); 405 return expr; 406 } 407 408 /// Makes a binary operation 409 Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) { 410 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 411 expr->get_args().push_back( lhs ); 412 expr->get_args().push_back( rhs ); 413 return expr; 414 } 415 416 /// Returns the dereference of a local pointer variable 417 Expression *derefVar( ObjectDecl *var ) { 418 return makeOp( "*?", new VariableExpr( var ) ); 419 } 420 421 /// makes an if-statement with a single-expression if-block and no then block 422 Statement *makeCond( Expression *cond, Expression *ifPart ) { 423 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 ); 424 } 425 426 /// makes a statement that assigns rhs to lhs if lhs < rhs 427 Statement *makeAssignMax( Expression *lhs, Expression *rhs ) { 428 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) ); 429 } 430 431 /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two) 432 Statement *makeAlignTo( Expression *lhs, Expression *rhs ) { 433 // check that the lhs is zeroed out to the level of rhs 434 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) ); 435 // if not aligned, increment to alignment 436 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) ); 437 return makeCond( ifCond, ifExpr ); 438 } 439 440 /// adds an expression to a compound statement 441 void addExpr( CompoundStmt *stmts, Expression *expr ) { 442 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) ); 443 } 444 445 /// adds a statement to a compound statement 446 void addStmt( CompoundStmt *stmts, Statement *stmt ) { 447 stmts->get_kids().push_back( stmt ); 448 } 449 450 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 451 // do not generate layout function for "empty" tag structs 452 if ( structDecl->get_members().empty() ) return structDecl; 453 454 // get parameters that can change layout, exiting early if none 455 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() ); 456 if ( otypeParams.empty() ) return structDecl; 457 458 // build layout function signature 459 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false ); 460 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 461 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 462 463 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 464 layoutFnType->get_parameters().push_back( sizeParam ); 465 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 466 layoutFnType->get_parameters().push_back( alignParam ); 467 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 468 layoutFnType->get_parameters().push_back( offsetParam ); 469 addOtypeParams( layoutFnType, otypeParams ); 470 471 // build function decl 472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType ); 473 474 // calculate struct layout in function body 475 476 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size 477 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) ); 478 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 479 unsigned long n_members = 0; 480 bool firstMember = true; 481 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) { 482 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 483 assert( dwt ); 484 Type *memberType = dwt->get_type(); 485 486 if ( firstMember ) { 487 firstMember = false; 488 } else { 489 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 490 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 491 } 492 493 // place current size in the current offset index 494 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ), 495 derefVar( sizeParam ) ) ); 496 ++n_members; 497 498 // add member size to current size 499 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 500 501 // take max of member alignment and global alignment 502 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); 503 } 504 // make sure the type is end-padded to a multiple of its alignment 505 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 506 507 addDeclarationAfter( layoutDecl ); 508 return structDecl; 509 } 510 511 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 512 // do not generate layout function for "empty" tag unions 513 if ( unionDecl->get_members().empty() ) return unionDecl; 514 515 // get parameters that can change layout, exiting early if none 516 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); 517 if ( otypeParams.empty() ) return unionDecl; 518 519 // build layout function signature 520 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false ); 521 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 522 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 523 524 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 525 layoutFnType->get_parameters().push_back( sizeParam ); 526 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 527 layoutFnType->get_parameters().push_back( alignParam ); 528 addOtypeParams( layoutFnType, otypeParams ); 529 530 // build function decl 531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType ); 532 533 // calculate union layout in function body 534 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 535 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) ); 536 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) { 537 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 538 assert( dwt ); 539 Type *memberType = dwt->get_type(); 540 541 // take max member size and global size 542 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 543 544 // take max of member alignment and global alignment 545 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); 546 } 547 // make sure the type is end-padded to a multiple of its alignment 548 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 549 550 addDeclarationAfter( layoutDecl ); 551 return unionDecl; 552 } 553 208 554 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 209 555 … … 245 591 } 246 592 247 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 248 adapters.push(AdapterMap()); 249 } 593 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {} 250 594 251 595 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise … … 350 694 } // for 351 695 352 AdapterMap & adapters = Pass1::adapters.top();353 696 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 354 697 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); … … 772 1115 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 773 1116 774 AdapterMap & adapters = Pass1::adapters.top();775 Adapter Map::iterator adapter = adapters.find( mangleName );1117 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 1118 AdapterIter adapter = adapters.find( mangleName ); 776 1119 if ( adapter == adapters.end() ) { 777 1120 // adapter has not been created yet in the current scope, so define it 778 1121 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 779 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1122 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 1123 adapter = answer.first; 780 1124 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 781 1125 } // if … … 1156 1500 1157 1501 void Pass1::doBeginScope() { 1158 // push a copy of the current map 1159 adapters.push(adapters.top()); 1502 adapters.beginScope(); 1160 1503 scopedAssignOps.beginScope(); 1161 1504 } 1162 1505 1163 1506 void Pass1::doEndScope() { 1164 adapters. pop();1507 adapters.endScope(); 1165 1508 scopedAssignOps.endScope(); 1166 1509 } … … 1309 1652 } 1310 1653 1654 //////////////////////////////////////// GenericInstantiator ////////////////////////////////////////////////// 1655 1656 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 1657 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 1658 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 1659 1660 // substitute concrete types for given parameters, and incomplete types for placeholders 1661 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1662 std::list< Expression* >::const_iterator param = params.begin(); 1663 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 1664 // switch ( (*baseParam)->get_kind() ) { 1665 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 1666 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 1667 assert(paramType && "Aggregate parameters should be type expressions"); 1668 out.push_back( paramType->clone() ); 1669 // check that the substituted type isn't a type variable itself 1670 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 1671 allConcrete = false; 1672 } 1673 // break; 1674 // } 1675 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1676 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1677 // break; 1678 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1679 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1680 // break; 1681 // } 1682 } 1683 1684 // if any parameters left over, not done 1685 if ( baseParam != baseParams.end() ) return false; 1686 // // if not enough parameters given, substitute remaining incomplete types for placeholders 1687 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 1688 // switch ( (*baseParam)->get_kind() ) { 1689 // case TypeDecl::Any: // no more substitutions here, fail early 1690 // return false; 1691 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1692 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1693 // break; 1694 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1695 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1696 // break; 1697 // } 1698 // } 1699 1700 return allConcrete; 1701 } 1702 1703 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 1704 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 1705 std::list< Declaration* >& out ) { 1706 // substitute types into new members 1707 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 1708 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 1709 Declaration *newMember = (*member)->clone(); 1710 subs.apply(newMember); 1711 out.push_back( newMember ); 1712 } 1713 } 1714 1715 Type* GenericInstantiator::mutate( StructInstType *inst ) { 1716 // mutate subtypes 1717 Type *mutated = Mutator::mutate( inst ); 1718 inst = dynamic_cast< StructInstType* >( mutated ); 1719 if ( ! inst ) return mutated; 1720 1721 // exit early if no need for further mutation 1722 if ( inst->get_parameters().empty() ) return inst; 1723 assert( inst->get_baseParameters() && "Base struct has parameters" ); 1724 1725 // check if type can be concretely instantiated; put substitutions into typeSubs 1726 std::list< TypeExpr* > typeSubs; 1727 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1728 deleteAll( typeSubs ); 1729 return inst; 1730 } 1731 1732 // make concrete instantiation of generic type 1733 StructDecl *concDecl = lookup( inst, typeSubs ); 1734 if ( ! concDecl ) { 1735 // set concDecl to new type, insert type declaration into statements to add 1736 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) ); 1737 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1738 DeclMutator::addDeclaration( concDecl ); 1739 insert( inst, typeSubs, concDecl ); 1740 } 1741 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 1742 newInst->set_baseStruct( concDecl ); 1743 1744 deleteAll( typeSubs ); 1745 delete inst; 1746 return newInst; 1747 } 1748 1749 Type* GenericInstantiator::mutate( UnionInstType *inst ) { 1750 // mutate subtypes 1751 Type *mutated = Mutator::mutate( inst ); 1752 inst = dynamic_cast< UnionInstType* >( mutated ); 1753 if ( ! inst ) return mutated; 1754 1755 // exit early if no need for further mutation 1756 if ( inst->get_parameters().empty() ) return inst; 1757 assert( inst->get_baseParameters() && "Base union has parameters" ); 1758 1759 // check if type can be concretely instantiated; put substitutions into typeSubs 1760 std::list< TypeExpr* > typeSubs; 1761 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1762 deleteAll( typeSubs ); 1763 return inst; 1764 } 1765 1766 // make concrete instantiation of generic type 1767 UnionDecl *concDecl = lookup( inst, typeSubs ); 1768 if ( ! concDecl ) { 1769 // set concDecl to new type, insert type declaration into statements to add 1770 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) ); 1771 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1772 DeclMutator::addDeclaration( concDecl ); 1773 insert( inst, typeSubs, concDecl ); 1774 } 1775 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 1776 newInst->set_baseUnion( concDecl ); 1777 1778 deleteAll( typeSubs ); 1779 delete inst; 1780 return newInst; 1781 } 1782 1783 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 1784 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 1785 // // get variable for member aggregate 1786 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 1787 // if ( ! varExpr ) return NULL; 1788 // 1789 // // get object for variable 1790 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1791 // if ( ! objectDecl ) return NULL; 1792 // 1793 // // get base declaration from object type 1794 // Type *objectType = objectDecl->get_type(); 1795 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 1796 // if ( structType ) return structType->get_baseStruct(); 1797 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 1798 // if ( unionType ) return unionType->get_baseUnion(); 1799 // 1800 // return NULL; 1801 // } 1802 // 1803 // /// Finds the declaration with the given name, returning decls.end() if none such 1804 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 1805 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 1806 // if ( (*decl)->get_name() == name ) return decl; 1807 // } 1808 // return decls.end(); 1809 // } 1810 // 1811 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 1812 // // mutate, exiting early if no longer MemberExpr 1813 // Expression *expr = Mutator::mutate( memberExpr ); 1814 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 1815 // if ( ! memberExpr ) return expr; 1816 // 1817 // // get declaration of member and base declaration of member, exiting early if not found 1818 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 1819 // if ( ! memberBase ) return memberExpr; 1820 // DeclarationWithType *memberDecl = memberExpr->get_member(); 1821 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 1822 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 1823 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 1824 // if ( ! baseDecl ) return memberExpr; 1825 // 1826 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 1827 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 1828 // SymTab::Indexer dummy; 1829 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 1830 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 1831 // } 1832 1833 void GenericInstantiator::doBeginScope() { 1834 DeclMutator::doBeginScope(); 1835 instantiations.beginScope(); 1836 } 1837 1838 void GenericInstantiator::doEndScope() { 1839 DeclMutator::doEndScope(); 1840 instantiations.endScope(); 1841 } 1842 1311 1843 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1312 1844 -
src/GenPoly/DeclMutator.cc
rb63e376 rae357ec 24 24 } 25 25 26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {}26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {} 27 27 28 28 DeclMutator::~DeclMutator() {} 29 29 30 30 void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) { 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 31 for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) { 32 // splice in new declarations after previous decl 33 decls.splice( decl, declsToAddAfter.back() ); 34 35 if ( decl == decls.end() ) break; 36 32 37 // run mutator on declaration 33 38 *decl = maybeMutate( *decl, *this ); … … 39 44 40 45 void DeclMutator::doBeginScope() { 41 // add new decl list for inside of scope46 // add new decl lists for inside of scope 42 47 declsToAdd.resize( declsToAdd.size()+1 ); 48 declsToAddAfter.resize( declsToAddAfter.size()+1 ); 43 49 } 44 50 … … 49 55 newBack->splice( newBack->end(), *back ); 50 56 declsToAdd.pop_back(); 57 58 back = declsToAddAfter.rbegin(); 59 newBack = back + 1; 60 newBack->splice( newBack->end(), *back ); 61 declsToAddAfter.pop_back(); 51 62 } 52 63 … … 61 72 stmt = maybeMutate( stmt, *this ); 62 73 // return if no declarations to add 63 if ( declsToAdd.back().empty() ) return stmt; 74 if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) { 75 doEndScope(); 76 return stmt; 77 } 64 78 65 79 // otherwise add declarations to new compound statement … … 71 85 declsToAdd.back().clear(); 72 86 87 // add mutated statement 88 compound->get_kids().push_back( stmt ); 89 90 // add declarations after to new compound statement 91 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { 92 DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); 93 compound->get_kids().push_back( declStmt ); 94 } 95 declsToAddAfter.back().clear(); 96 73 97 doEndScope(); 74 75 // add mutated statement and return76 compound->get_kids().push_back( stmt );77 98 return compound; 78 99 } … … 80 101 void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) { 81 102 doBeginScope(); 103 82 104 83 for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) { 105 for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) { 106 // add any new declarations after the previous statement 107 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { 108 DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); 109 stmts.insert( stmt, declStmt ); 110 } 111 declsToAddAfter.back().clear(); 112 113 if ( stmt == stmts.end() ) break; 114 84 115 // run mutator on statement 85 116 *stmt = maybeMutate( *stmt, *this ); … … 92 123 declsToAdd.back().clear(); 93 124 } 94 125 95 126 doEndScope(); 96 127 } … … 98 129 void DeclMutator::addDeclaration( Declaration *decl ) { 99 130 declsToAdd.back().push_back( decl ); 131 } 132 133 void DeclMutator::addDeclarationAfter( Declaration *decl ) { 134 declsToAddAfter.back().push_back( decl ); 100 135 } 101 136 -
src/GenPoly/DeclMutator.h
rb63e376 rae357ec 55 55 /// Add a declaration to the list to be added before the current position 56 56 void addDeclaration( Declaration* decl ); 57 /// Add a declaration to the list to be added after the current position 58 void addDeclarationAfter( Declaration* decl ); 57 59 private: 58 60 /// A stack of declarations to add before the current declaration or statement 59 61 std::vector< std::list< Declaration* > > declsToAdd; 62 /// A stack of declarations to add after the current declaration or statement 63 std::vector< std::list< Declaration* > > declsToAddAfter; 60 64 }; 61 65 } // namespace -
src/GenPoly/module.mk
rb63e376 rae357ec 23 23 GenPoly/CopyParams.cc \ 24 24 GenPoly/FindFunction.cc \ 25 GenPoly/InstantiateGeneric.cc \26 25 GenPoly/DeclMutator.cc -
src/Makefile.in
rb63e376 rae357ec 122 122 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \ 123 123 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 124 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \125 124 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \ 126 125 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \ … … 154 153 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \ 155 154 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 156 SymTab/driver_cfa_cpp-IdTable.$(OBJEXT) \157 155 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 158 156 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 347 345 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 348 346 GenPoly/CopyParams.cc GenPoly/FindFunction.cc \ 349 GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \ 350 InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \ 351 Parser/TypedefTable.cc Parser/ParseNode.cc \ 352 Parser/DeclarationNode.cc Parser/ExpressionNode.cc \ 353 Parser/StatementNode.cc Parser/InitializerNode.cc \ 354 Parser/TypeData.cc Parser/LinkageSpec.cc \ 355 Parser/parseutility.cc Parser/Parser.cc \ 347 GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \ 348 Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \ 349 Parser/ParseNode.cc Parser/DeclarationNode.cc \ 350 Parser/ExpressionNode.cc Parser/StatementNode.cc \ 351 Parser/InitializerNode.cc Parser/TypeData.cc \ 352 Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \ 356 353 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 357 354 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ … … 362 359 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 363 360 ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \ 364 ResolvExpr/TypeEnvironment.cc SymTab/IdTable.cc \ 365 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 366 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 367 SymTab/TypeEquality.cc SynTree/Type.cc SynTree/VoidType.cc \ 368 SynTree/BasicType.cc SynTree/PointerType.cc \ 369 SynTree/ArrayType.cc SynTree/FunctionType.cc \ 370 SynTree/ReferenceToType.cc SynTree/TupleType.cc \ 371 SynTree/TypeofType.cc SynTree/AttrType.cc \ 361 ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \ 362 SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \ 363 SymTab/ImplementationType.cc SymTab/TypeEquality.cc \ 364 SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \ 365 SynTree/PointerType.cc SynTree/ArrayType.cc \ 366 SynTree/FunctionType.cc SynTree/ReferenceToType.cc \ 367 SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \ 372 368 SynTree/VarArgsType.cc SynTree/Constant.cc \ 373 369 SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 556 552 GenPoly/$(DEPDIR)/$(am__dirstamp) 557 553 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ 558 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)559 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT): \560 554 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 561 555 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \ … … 664 658 @$(MKDIR_P) SymTab/$(DEPDIR) 665 659 @: > SymTab/$(DEPDIR)/$(am__dirstamp) 666 SymTab/driver_cfa_cpp-IdTable.$(OBJEXT): SymTab/$(am__dirstamp) \667 SymTab/$(DEPDIR)/$(am__dirstamp)668 660 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \ 669 661 SymTab/$(DEPDIR)/$(am__dirstamp) … … 796 788 -rm -f GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) 797 789 -rm -f GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) 798 -rm -f GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT)799 790 -rm -f GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) 800 791 -rm -f GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) … … 832 823 -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT) 833 824 -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) 834 -rm -f SymTab/driver_cfa_cpp-IdTable.$(OBJEXT)835 825 -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) 836 826 -rm -f SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) … … 903 893 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 904 894 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@ 905 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@906 895 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@ 907 896 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@ … … 939 928 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@ 940 929 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@ 941 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po@am__quote@942 930 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@ 943 931 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@ … … 1364 1352 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi` 1365 1353 1366 GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc1367 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc1368 @am__fastdepCXX_TRUE@ $(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po1369 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.o' libtool=no @AMDEPBACKSLASH@1370 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1371 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc1372 1373 GenPoly/driver_cfa_cpp-InstantiateGeneric.obj: GenPoly/InstantiateGeneric.cc1374 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`1375 @am__fastdepCXX_TRUE@ $(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po1376 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.obj' libtool=no @AMDEPBACKSLASH@1377 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1378 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`1379 1380 1354 GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc 1381 1355 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc … … 1811 1785 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1812 1786 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi` 1813 1814 SymTab/driver_cfa_cpp-IdTable.o: SymTab/IdTable.cc1815 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc1816 @am__fastdepCXX_TRUE@ $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po1817 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.o' libtool=no @AMDEPBACKSLASH@1818 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1819 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc1820 1821 SymTab/driver_cfa_cpp-IdTable.obj: SymTab/IdTable.cc1822 @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`1823 @am__fastdepCXX_TRUE@ $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po1824 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.obj' libtool=no @AMDEPBACKSLASH@1825 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@1826 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`1827 1787 1828 1788 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc -
src/SymTab/Indexer.cc
rb63e376 rae357ec 14 14 // 15 15 16 #include "Indexer.h" 17 18 #include <string> 19 #include <typeinfo> 20 #include <unordered_map> 21 #include <utility> 22 23 #include "Mangler.h" 24 25 #include "Common/utility.h" 26 27 #include "ResolvExpr/typeops.h" 28 16 29 #include "SynTree/Declaration.h" 17 30 #include "SynTree/Type.h" … … 19 32 #include "SynTree/Initializer.h" 20 33 #include "SynTree/Statement.h" 21 #include "Indexer.h"22 #include <typeinfo>23 #include "Common/utility.h"24 34 25 35 #define debugPrint(x) if ( doDebug ) { std::cout << x; } … … 33 43 } 34 44 35 Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {} 36 37 Indexer::~Indexer() {} 45 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 46 typedef std::unordered_map< std::string, MangleTable > IdTable; 47 typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable; 48 typedef std::unordered_map< std::string, StructDecl* > StructTable; 49 typedef std::unordered_map< std::string, EnumDecl* > EnumTable; 50 typedef std::unordered_map< std::string, UnionDecl* > UnionTable; 51 typedef std::unordered_map< std::string, TraitDecl* > TraitTable; 52 53 void dump( const IdTable &table, std::ostream &os ) { 54 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) { 55 for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) { 56 os << mangle->second << std::endl; 57 } 58 } 59 } 60 61 template< typename Decl > 62 void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) { 63 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) { 64 os << it->second << std::endl; 65 } // for 66 } 67 68 struct Indexer::Impl { 69 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(), 70 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 71 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ), 72 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {} 73 unsigned long refCount; ///< Number of references to these tables 74 unsigned long scope; ///< Scope these tables are associated with 75 unsigned long size; ///< Number of elements stored in this table 76 const Indexer base; ///< Base indexer this extends 77 78 IdTable idTable; ///< Identifier namespace 79 TypeTable typeTable; ///< Type namespace 80 StructTable structTable; ///< Struct namespace 81 EnumTable enumTable; ///< Enum namespace 82 UnionTable unionTable; ///< Union namespace 83 TraitTable traitTable; ///< Trait namespace 84 }; 85 86 Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) { 87 if ( ! toClone ) return 0; 88 89 // shorten the search chain by skipping empty links 90 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone; 91 if ( ret ) { ++ret->refCount; } 92 93 return ret; 94 } 95 96 void Indexer::deleteRef( Indexer::Impl *toFree ) { 97 if ( ! toFree ) return; 98 99 if ( --toFree->refCount == 0 ) delete toFree; 100 } 101 102 void Indexer::makeWritable() { 103 if ( ! tables ) { 104 // create indexer if not yet set 105 tables = new Indexer::Impl( scope ); 106 } else if ( tables->refCount > 1 || tables->scope != scope ) { 107 // make this indexer the base of a fresh indexer at the current scope 108 tables = new Indexer::Impl( scope, std::move( *this ) ); 109 } 110 } 111 112 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {} 113 114 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {} 115 116 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) { 117 that.tables = 0; 118 } 119 120 Indexer::~Indexer() { 121 deleteRef( tables ); 122 } 123 124 Indexer& Indexer::operator= ( const Indexer &that ) { 125 deleteRef( tables ); 126 127 tables = newRef( that.tables ); 128 scope = that.scope; 129 doDebug = that.doDebug; 130 131 return *this; 132 } 133 134 Indexer& Indexer::operator= ( Indexer &&that ) { 135 deleteRef( tables ); 136 137 tables = that.tables; 138 scope = that.scope; 139 doDebug = that.doDebug; 140 141 that.tables = 0; 142 143 return *this; 144 } 38 145 39 146 void Indexer::visit( ObjectDecl *objectDecl ) { … … 45 152 if ( objectDecl->get_name() != "" ) { 46 153 debugPrint( "Adding object " << objectDecl->get_name() << std::endl ); 47 idTable.addDecl( objectDecl );154 addId( objectDecl ); 48 155 } // if 49 156 } … … 52 159 if ( functionDecl->get_name() == "" ) return; 53 160 debugPrint( "Adding function " << functionDecl->get_name() << std::endl ); 54 idTable.addDecl( functionDecl );161 addId( functionDecl ); 55 162 enterScope(); 56 163 maybeAccept( functionDecl->get_functionType(), *this ); … … 90 197 leaveScope(); 91 198 debugPrint( "Adding type " << typeDecl->get_name() << std::endl ); 92 typeTable.add( typeDecl );199 addType( typeDecl ); 93 200 acceptAll( typeDecl->get_assertions(), *this ); 94 201 } … … 100 207 leaveScope(); 101 208 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl ); 102 typeTable.add( typeDecl );209 addType( typeDecl ); 103 210 } 104 211 … … 108 215 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 109 216 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl ); 110 structTable.add( &fwdDecl );217 addStruct( &fwdDecl ); 111 218 112 219 enterScope(); … … 117 224 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl ); 118 225 // this addition replaces the forward declaration 119 structTable.add( aggregateDecl );226 addStruct( aggregateDecl ); 120 227 } 121 228 … … 125 232 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 126 233 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl ); 127 unionTable.add( &fwdDecl );234 addUnion( &fwdDecl ); 128 235 129 236 enterScope(); … … 133 240 134 241 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl ); 135 unionTable.add( aggregateDecl );242 addUnion( aggregateDecl ); 136 243 } 137 244 138 245 void Indexer::visit( EnumDecl *aggregateDecl ) { 139 246 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl ); 140 enumTable.add( aggregateDecl );247 addEnum( aggregateDecl ); 141 248 // unlike structs, contexts, and unions, enums inject their members into the global scope 142 249 acceptAll( aggregateDecl->get_members(), *this ); … … 150 257 151 258 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl ); 152 contextTable.add( aggregateDecl );259 addTrait( aggregateDecl ); 153 260 } 154 261 … … 299 406 300 407 void Indexer::visit( StructInstType *structInst ) { 301 if ( ! structTable.lookup( structInst->get_name() ) ) {408 if ( ! lookupStruct( structInst->get_name() ) ) { 302 409 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl ); 303 structTable.add( structInst->get_name() );410 addStruct( structInst->get_name() ); 304 411 } 305 412 enterScope(); … … 309 416 310 417 void Indexer::visit( UnionInstType *unionInst ) { 311 if ( ! unionTable.lookup( unionInst->get_name() ) ) {418 if ( ! lookupUnion( unionInst->get_name() ) ) { 312 419 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl ); 313 unionTable.add( unionInst->get_name() );420 addUnion( unionInst->get_name() ); 314 421 } 315 422 enterScope(); … … 325 432 } 326 433 327 328 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const { 329 idTable.lookupId( id, list ); 330 } 331 332 DeclarationWithType* Indexer::lookupId( const std::string &id) const { 333 return idTable.lookupId(id); 434 435 436 void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const { 437 if ( ! tables ) return; 438 439 IdTable::const_iterator decls = tables->idTable.find( id ); 440 if ( decls != tables->idTable.end() ) { 441 const MangleTable &mangleTable = decls->second; 442 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 443 out.push_back( decl->second ); 444 } 445 } 446 447 // get declarations from base indexers 448 tables->base.lookupId( id, out ); 334 449 } 335 450 336 451 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 337 return typeTable.lookup( id ); 452 if ( ! tables ) return 0; 453 454 TypeTable::const_iterator ret = tables->typeTable.find( id ); 455 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id ); 338 456 } 339 457 340 458 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 341 return structTable.lookup( id ); 459 if ( ! tables ) return 0; 460 461 StructTable::const_iterator ret = tables->structTable.find( id ); 462 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id ); 342 463 } 343 464 344 465 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 345 return enumTable.lookup( id ); 466 if ( ! tables ) return 0; 467 468 EnumTable::const_iterator ret = tables->enumTable.find( id ); 469 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id ); 346 470 } 347 471 348 472 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 349 return unionTable.lookup( id ); 350 } 351 352 TraitDecl * Indexer::lookupTrait( const std::string &id ) const { 353 return contextTable.lookup( id ); 473 if ( ! tables ) return 0; 474 475 UnionTable::const_iterator ret = tables->unionTable.find( id ); 476 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id ); 477 } 478 479 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 480 if ( ! tables ) return 0; 481 482 TraitTable::const_iterator ret = tables->traitTable.find( id ); 483 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id ); 484 } 485 486 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 487 if ( ! tables ) return 0; 488 if ( tables->scope < scope ) return 0; 489 490 IdTable::const_iterator decls = tables->idTable.find( id ); 491 if ( decls != tables->idTable.end() ) { 492 const MangleTable &mangleTable = decls->second; 493 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 494 if ( decl != mangleTable.end() ) return decl->second; 495 } 496 497 return tables->base.lookupIdAtScope( id, mangleName, scope ); 498 } 499 500 bool Indexer::hasCDeclWithName( const std::string &id ) const { 501 if ( ! tables ) return false; 502 503 IdTable::const_iterator decls = tables->idTable.find( id ); 504 if ( decls != tables->idTable.end() ) { 505 const MangleTable &mangleTable = decls->second; 506 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 507 if ( decl->second->get_linkage() == LinkageSpec::C ) return true; 508 } 509 } 510 511 return tables->base.hasCDeclWithName( id ); 512 } 513 514 NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const { 515 if ( ! tables ) return 0; 516 if ( tables->scope < scope ) return 0; 517 518 TypeTable::const_iterator ret = tables->typeTable.find( id ); 519 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope ); 520 } 521 522 StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const { 523 if ( ! tables ) return 0; 524 if ( tables->scope < scope ) return 0; 525 526 StructTable::const_iterator ret = tables->structTable.find( id ); 527 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope ); 528 } 529 530 EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const { 531 if ( ! tables ) return 0; 532 if ( tables->scope < scope ) return 0; 533 534 EnumTable::const_iterator ret = tables->enumTable.find( id ); 535 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope ); 536 } 537 538 UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const { 539 if ( ! tables ) return 0; 540 if ( tables->scope < scope ) return 0; 541 542 UnionTable::const_iterator ret = tables->unionTable.find( id ); 543 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope ); 544 } 545 546 TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const { 547 if ( ! tables ) return 0; 548 if ( tables->scope < scope ) return 0; 549 550 TraitTable::const_iterator ret = tables->traitTable.find( id ); 551 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope ); 552 } 553 554 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) { 555 // if we're giving the same name mangling to things of different types then there is something wrong 556 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) ) 557 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) ); 558 559 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) { 560 // new definition shadows the autogenerated one, even at the same scope 561 return false; 562 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 563 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 564 // we should ignore outermost pointer qualifiers, except _Atomic? 565 FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added ); 566 FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing ); 567 if ( newentry && oldentry ) { 568 if ( newentry->get_statements() && oldentry->get_statements() ) { 569 throw SemanticError( "duplicate function definition for ", added ); 570 } // if 571 } else { 572 // two objects with the same mangled name defined in the same scope. 573 // both objects must be marked extern or both must be intrinsic for this to be okay 574 // xxx - perhaps it's actually if either is intrinsic then this is okay? 575 // might also need to be same storage class? 576 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added ); 577 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing ); 578 if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) { 579 throw SemanticError( "duplicate object definition for ", added ); 580 } // if 581 } // if 582 } else { 583 throw SemanticError( "duplicate definition for ", added ); 584 } // if 585 586 return true; 587 } 588 589 void Indexer::addId( DeclarationWithType *decl ) { 590 makeWritable(); 591 592 const std::string &name = decl->get_name(); 593 std::string mangleName; 594 if ( decl->get_linkage() == LinkageSpec::C ) { 595 mangleName = name; 596 } else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) { 597 // mangle the name without including the appropriate suffix, so overridable routines are placed into the 598 // same "bucket" as their user defined versions. 599 mangleName = Mangler::mangle( decl, false ); 600 } else { 601 mangleName = Mangler::mangle( decl ); 602 } // if 603 604 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope ); 605 if ( ! existing || ! addedIdConflicts( existing, decl ) ) { 606 // this ensures that no two declarations with the same unmangled name both have C linkage 607 if ( decl->get_linkage() == LinkageSpec::C && hasCDeclWithName( name ) ) { 608 throw SemanticError( "invalid overload of C function ", decl ); 609 } 610 611 tables->idTable[ name ][ mangleName ] = decl; 612 ++tables->size; 613 } 614 } 615 616 bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) { 617 if ( existing->get_base() == 0 ) { 618 return false; 619 } else if ( added->get_base() == 0 ) { 620 return true; 621 } else { 622 throw SemanticError( "redeclaration of ", added ); 623 } 624 } 625 626 void Indexer::addType( NamedTypeDecl *decl ) { 627 makeWritable(); 628 629 const std::string &id = decl->get_name(); 630 TypeTable::iterator existing = tables->typeTable.find( id ); 631 if ( existing == tables->typeTable.end() ) { 632 NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope ); 633 if ( ! parent || ! addedTypeConflicts( parent, decl ) ) { 634 tables->typeTable.insert( existing, std::make_pair( id, decl ) ); 635 ++tables->size; 636 } 637 } else { 638 if ( ! addedTypeConflicts( existing->second, decl ) ) { 639 existing->second = decl; 640 } 641 } 642 } 643 644 bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) { 645 if ( existing->get_members().empty() ) { 646 return false; 647 } else if ( ! added->get_members().empty() ) { 648 throw SemanticError( "redeclaration of ", added ); 649 } // if 650 return true; 651 } 652 653 void Indexer::addStruct( const std::string &id ) { 654 addStruct( new StructDecl( id ) ); 655 } 656 657 void Indexer::addStruct( StructDecl *decl ) { 658 makeWritable(); 659 660 const std::string &id = decl->get_name(); 661 StructTable::iterator existing = tables->structTable.find( id ); 662 if ( existing == tables->structTable.end() ) { 663 StructDecl *parent = tables->base.lookupStructAtScope( id, scope ); 664 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 665 tables->structTable.insert( existing, std::make_pair( id, decl ) ); 666 ++tables->size; 667 } 668 } else { 669 if ( ! addedDeclConflicts( existing->second, decl ) ) { 670 existing->second = decl; 671 } 672 } 673 } 674 675 void Indexer::addEnum( EnumDecl *decl ) { 676 makeWritable(); 677 678 const std::string &id = decl->get_name(); 679 EnumTable::iterator existing = tables->enumTable.find( id ); 680 if ( existing == tables->enumTable.end() ) { 681 EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope ); 682 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 683 tables->enumTable.insert( existing, std::make_pair( id, decl ) ); 684 ++tables->size; 685 } 686 } else { 687 if ( ! addedDeclConflicts( existing->second, decl ) ) { 688 existing->second = decl; 689 } 690 } 691 } 692 693 void Indexer::addUnion( const std::string &id ) { 694 addUnion( new UnionDecl( id ) ); 695 } 696 697 void Indexer::addUnion( UnionDecl *decl ) { 698 makeWritable(); 699 700 const std::string &id = decl->get_name(); 701 UnionTable::iterator existing = tables->unionTable.find( id ); 702 if ( existing == tables->unionTable.end() ) { 703 UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope ); 704 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 705 tables->unionTable.insert( existing, std::make_pair( id, decl ) ); 706 ++tables->size; 707 } 708 } else { 709 if ( ! addedDeclConflicts( existing->second, decl ) ) { 710 existing->second = decl; 711 } 712 } 713 } 714 715 void Indexer::addTrait( TraitDecl *decl ) { 716 makeWritable(); 717 718 const std::string &id = decl->get_name(); 719 TraitTable::iterator existing = tables->traitTable.find( id ); 720 if ( existing == tables->traitTable.end() ) { 721 TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope ); 722 if ( ! parent || ! addedDeclConflicts( parent, decl ) ) { 723 tables->traitTable.insert( existing, std::make_pair( id, decl ) ); 724 ++tables->size; 725 } 726 } else { 727 if ( ! addedDeclConflicts( existing->second, decl ) ) { 728 existing->second = decl; 729 } 730 } 354 731 } 355 732 356 733 void Indexer::enterScope() { 734 ++scope; 735 357 736 if ( doDebug ) { 358 std::cout << "--- Entering scope" << std::endl; 359 } 360 idTable.enterScope(); 361 typeTable.enterScope(); 362 structTable.enterScope(); 363 enumTable.enterScope(); 364 unionTable.enterScope(); 365 contextTable.enterScope(); 737 std::cout << "--- Entering scope " << scope << std::endl; 738 } 366 739 } 367 740 368 741 void Indexer::leaveScope() { 369 742 using std::cout; 370 using std::endl; 371 372 if ( doDebug ) { 373 cout << "--- Leaving scope containing" << endl; 374 idTable.dump( cout ); 375 typeTable.dump( cout ); 376 structTable.dump( cout ); 377 enumTable.dump( cout ); 378 unionTable.dump( cout ); 379 contextTable.dump( cout ); 380 } 381 idTable.leaveScope(); 382 typeTable.leaveScope(); 383 structTable.leaveScope(); 384 enumTable.leaveScope(); 385 unionTable.leaveScope(); 386 contextTable.leaveScope(); 743 744 assert( scope > 0 && "cannot leave initial scope" ); 745 --scope; 746 747 while ( tables && tables->scope > scope ) { 748 if ( doDebug ) { 749 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl; 750 dump( tables->idTable, cout ); 751 dump( tables->typeTable, cout ); 752 dump( tables->structTable, cout ); 753 dump( tables->enumTable, cout ); 754 dump( tables->unionTable, cout ); 755 dump( tables->traitTable, cout ); 756 } 757 758 // swap tables for base table until we find one at an appropriate scope 759 Indexer::Impl *base = newRef( tables->base.tables ); 760 deleteRef( tables ); 761 tables = base; 762 } 387 763 } 388 764 389 765 void Indexer::print( std::ostream &os, int indent ) const { 390 766 using std::cerr; 391 using std::endl; 392 393 cerr << "===idTable===" << endl; 394 idTable.dump( os ); 395 cerr << "===typeTable===" << endl; 396 typeTable.dump( os ); 397 cerr << "===structTable===" << endl; 398 structTable.dump( os ); 399 cerr << "===enumTable===" << endl; 400 enumTable.dump( os ); 401 cerr << "===unionTable===" << endl; 402 unionTable.dump( os ); 403 cerr << "===contextTable===" << endl; 404 contextTable.dump( os ); 405 #if 0 406 idTable.dump( os ); 407 typeTable.dump( os ); 408 structTable.dump( os ); 409 enumTable.dump( os ); 410 unionTable.dump( os ); 411 contextTable.dump( os ); 412 #endif 767 768 cerr << "===idTable===" << std::endl; 769 if ( tables ) dump( tables->idTable, os ); 770 cerr << "===typeTable===" << std::endl; 771 if ( tables ) dump( tables->typeTable, os ); 772 cerr << "===structTable===" << std::endl; 773 if ( tables ) dump( tables->structTable, os ); 774 cerr << "===enumTable===" << std::endl; 775 if ( tables ) dump( tables->enumTable, os ); 776 cerr << "===unionTable===" << std::endl; 777 if ( tables ) dump( tables->unionTable, os ); 778 cerr << "===contextTable===" << std::endl; 779 if ( tables ) dump( tables->traitTable, os ); 413 780 } 414 781 } // namespace SymTab -
src/SymTab/Indexer.h
rb63e376 rae357ec 21 21 22 22 #include "SynTree/Visitor.h" 23 #include "IdTable.h"24 #include "AggregateTable.h"25 #include "TypeTable.h"26 23 27 24 namespace SymTab { … … 29 26 public: 30 27 Indexer( bool useDebug = false ); 28 29 Indexer( const Indexer &that ); 30 Indexer( Indexer &&that ); 31 31 virtual ~Indexer(); 32 Indexer& operator= ( const Indexer &that ); 33 Indexer& operator= ( Indexer &&that ); 32 34 33 35 //using Visitor::visit; … … 78 80 void leaveScope(); 79 81 80 void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const; 81 DeclarationWithType* lookupId( const std::string &id) const; 82 /// Gets all declarations with the given ID 83 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const; 84 /// Gets the top-most type declaration with the given ID 82 85 NamedTypeDecl *lookupType( const std::string &id ) const; 86 /// Gets the top-most struct declaration with the given ID 83 87 StructDecl *lookupStruct( const std::string &id ) const; 88 /// Gets the top-most enum declaration with the given ID 84 89 EnumDecl *lookupEnum( const std::string &id ) const; 90 /// Gets the top-most union declaration with the given ID 85 91 UnionDecl *lookupUnion( const std::string &id ) const; 92 /// Gets the top-most trait declaration with the given ID 86 93 TraitDecl *lookupTrait( const std::string &id ) const; 87 94 88 95 void print( std::ostream &os, int indent = 0 ) const; 89 96 private: 90 IdTable idTable; 91 TypeTable typeTable; 92 StructTable structTable; 93 EnumTable enumTable; 94 UnionTable unionTable; 95 TraitTable contextTable; 96 97 bool doDebug; // display debugging trace 97 /// looks up a specific mangled ID at the given scope 98 DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 99 /// returns true if there exists a declaration with C linkage and the given name 100 bool hasCDeclWithName( const std::string &id ) const; 101 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope) 102 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const; 103 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const; 104 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const; 105 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const; 106 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 107 108 void addId( DeclarationWithType *decl ); 109 void addType( NamedTypeDecl *decl ); 110 void addStruct( const std::string &id ); 111 void addStruct( StructDecl *decl ); 112 void addEnum( EnumDecl *decl ); 113 void addUnion( const std::string &id ); 114 void addUnion( UnionDecl *decl ); 115 void addTrait( TraitDecl *decl ); 116 117 struct Impl; 118 Impl *tables; ///< Copy-on-write instance of table data structure 119 unsigned long scope; ///< Scope index of this pointer 120 bool doDebug; ///< Display debugging trace? 121 122 /// Takes a new ref to a table (returns null if null) 123 static Impl *newRef( Impl *toClone ); 124 /// Clears a ref to a table (does nothing if null) 125 static void deleteRef( Impl *toFree ); 126 127 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) 128 void makeWritable(); 98 129 }; 99 130 } // namespace SymTab -
src/SymTab/module.mk
rb63e376 rae357ec 15 15 ############################################################################### 16 16 17 SRC += SymTab/IdTable.cc \ 18 SymTab/Indexer.cc \ 17 SRC += SymTab/Indexer.cc \ 19 18 SymTab/Mangler.cc \ 20 19 SymTab/Validate.cc \ -
src/SynTree/Constant.cc
rb63e376 rae357ec 16 16 #include <iostream> 17 17 #include <list> 18 #include <string> 18 19 19 20 #include "Constant.h" … … 28 29 29 30 Constant::~Constant() { delete type; } 31 32 Constant Constant::from( int i ) { 33 return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) ); 34 } 35 36 Constant Constant::from( unsigned long i ) { 37 return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) ); 38 } 39 40 Constant Constant::from( double d ) { 41 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) ); 42 } 30 43 31 44 Constant *Constant::clone() const { assert( false ); return 0; } -
src/SynTree/Constant.h
rb63e376 rae357ec 32 32 void set_value( std::string newValue ) { value = newValue; } 33 33 34 /// generates an integer constant of the given int 35 static Constant from( int i ); 36 /// generates an integer constant of the given unsigned long int 37 static Constant from( unsigned long i ); 38 /// generates a floating point constant of the given double 39 static Constant from( double d ); 40 34 41 virtual Constant *clone() const; 35 42 virtual void accept( Visitor &v ) { v.visit( this ); }
Note: See TracChangeset
for help on using the changeset viewer.