Changeset e67991f for src/AST/SymbolTable.cpp
- Timestamp:
- Jul 16, 2019, 10:38:32 AM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 6f15121
- Parents:
- 7dc2e57b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/SymbolTable.cpp
r7dc2e57b re67991f 73 73 74 74 SymbolTable::SymbolTable() 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 75 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 76 76 prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; } 77 77 … … 171 171 } 172 172 173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Node* deleter ) {173 void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) { 174 174 // default handling of conflicts is to raise an error 175 175 addId( decl, OnConflict::error(), nullptr, deleter ); … … 189 189 } 190 190 } 191 // does not need to be added to the table if both existing and added have a base that are 191 // does not need to be added to the table if both existing and added have a base that are 192 192 // the same 193 193 return true; … … 209 209 const std::string &id = decl->name; 210 210 211 if ( ! typeTable ) { 211 if ( ! typeTable ) { 212 212 typeTable = TypeTable::new_ptr(); 213 213 } else { 214 214 ++*stats().map_lookups; 215 215 auto existing = typeTable->find( id ); 216 if ( existing != typeTable->end() 217 && existing->second.scope == scope 216 if ( existing != typeTable->end() 217 && existing->second.scope == scope 218 218 && addedTypeConflicts( existing->second.decl, decl ) ) return; 219 219 } 220 220 221 221 lazyInitScope(); 222 222 ++*stats().map_mutations; … … 237 237 ++*stats().map_lookups; 238 238 auto existing = structTable->find( id ); 239 if ( existing != structTable->end() 240 && existing->second.scope == scope 239 if ( existing != structTable->end() 240 && existing->second.scope == scope 241 241 && addedDeclConflicts( existing->second.decl, decl ) ) return; 242 242 } … … 256 256 ++*stats().map_lookups; 257 257 auto existing = enumTable->find( id ); 258 if ( existing != enumTable->end() 259 && existing->second.scope == scope 258 if ( existing != enumTable->end() 259 && existing->second.scope == scope 260 260 && addedDeclConflicts( existing->second.decl, decl ) ) return; 261 261 } 262 262 263 263 lazyInitScope(); 264 264 ++*stats().map_mutations; … … 279 279 ++*stats().map_lookups; 280 280 auto existing = unionTable->find( id ); 281 if ( existing != unionTable->end() 282 && existing->second.scope == scope 281 if ( existing != unionTable->end() 282 && existing->second.scope == scope 283 283 && addedDeclConflicts( existing->second.decl, decl ) ) return; 284 284 } … … 298 298 ++*stats().map_lookups; 299 299 auto existing = traitTable->find( id ); 300 if ( existing != traitTable->end() 301 && existing->second.scope == scope 300 if ( existing != traitTable->end() 301 && existing->second.scope == scope 302 302 && addedDeclConflicts( existing->second.decl, decl ) ) return; 303 303 } … … 309 309 310 310 311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Node* withStmt ) {311 void SymbolTable::addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt ) { 312 312 for ( const Expr * expr : withExprs ) { 313 313 if ( ! expr->result ) continue; 314 314 const Type * resTy = expr->result->stripReferences(); 315 315 auto aggrType = dynamic_cast< const ReferenceToType * >( resTy ); 316 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 316 assertf( aggrType, "WithStmt expr has non-aggregate type: %s", 317 317 toString( expr->result ).c_str() ); 318 318 const AggregateDecl * aggr = aggrType->aggr(); 319 assertf( aggr, "WithStmt has null aggregate from type: %s", 319 assertf( aggr, "WithStmt has null aggregate from type: %s", 320 320 toString( expr->result ).c_str() ); 321 321 322 322 addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) ); 323 323 } … … 373 373 } 374 374 375 /// gets the declaration for the function acting on a type specified by otype key, 375 /// gets the declaration for the function acting on a type specified by otype key, 376 376 /// nullptr if none such 377 const FunctionDecl * getFunctionForOtype( 377 const FunctionDecl * getFunctionForOtype( 378 378 const DeclWithType * decl, const std::string & otypeKey ) { 379 379 auto func = dynamic_cast< const FunctionDecl * >( decl ); … … 383 383 } 384 384 385 bool SymbolTable::removeSpecialOverrides( 385 bool SymbolTable::removeSpecialOverrides( 386 386 SymbolTable::IdData & data, SymbolTable::MangleTable::Ptr & mangleTable ) { 387 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 388 // determine the set of ctor/dtor/assign that can be used by the requester. In particular, 389 // if the user defines a default ctor, then the generated default ctor is unavailable, 390 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 391 // field ctors are available. If the user defines any ctor then the generated default ctor 392 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 393 // anything that looks like a copy constructor, then the generated copy constructor is 387 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 388 // determine the set of ctor/dtor/assign that can be used by the requester. In particular, 389 // if the user defines a default ctor, then the generated default ctor is unavailable, 390 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 391 // field ctors are available. If the user defines any ctor then the generated default ctor 392 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 393 // anything that looks like a copy constructor, then the generated copy constructor is 394 394 // unavailable, and likewise for the assignment operator. 395 395 … … 450 450 // if this is the first user-defined function, delete non-user-defined overloads 451 451 std::vector< MangleTable::value_type > deleted; 452 452 453 453 for ( const auto& entry : *mangleTable ) { 454 454 // skip decls that aren't functions or are for the wrong type … … 489 489 if ( dataIsCopyFunc ) { 490 490 // remove current function if exists a user-defined copy function 491 // since the signatures for copy functions don't need to match exactly, using 491 // since the signatures for copy functions don't need to match exactly, using 492 492 // a delete statement is the wrong approach 493 493 if ( InitTweak::isCopyFunction( decl ) ) return false; … … 499 499 } 500 500 } 501 501 502 502 // nothing (more) to fix, return true 503 503 return true; … … 525 525 526 526 bool SymbolTable::addedIdConflicts( 527 const SymbolTable::IdData & existing, const DeclWithType * added, 528 SymbolTable::OnConflict handleConflicts, const Node* deleter ) {529 // if we're giving the same name mangling to things of different types then there is something 527 const SymbolTable::IdData & existing, const DeclWithType * added, 528 SymbolTable::OnConflict handleConflicts, const Decl * deleter ) { 529 // if we're giving the same name mangling to things of different types then there is something 530 530 // wrong 531 531 assert( (isObject( added ) && isObject( existing.id ) ) 532 532 || ( isFunction( added ) && isFunction( existing.id ) ) ); 533 533 534 534 if ( existing.id->linkage.is_overrideable ) { 535 535 // new definition shadows the autogenerated one, even at the same scope 536 536 return false; 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 537 } else if ( existing.id->linkage.is_mangled 538 || ResolvExpr::typesCompatible( 539 539 added->get_type(), existing.id->get_type(), SymbolTable{} ) ) { 540 540 541 541 // it is a conflict if one declaration is deleted and the other is not 542 542 if ( deleter && ! existing.deleter ) { … … 555 555 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 556 556 if ( handleConflicts.mode == OnConflict::Error ) { 557 SemanticError( added, 558 isFunction( added ) ? 559 "duplicate function definition for " : 557 SemanticError( added, 558 isFunction( added ) ? 559 "duplicate function definition for " : 560 560 "duplicate object definition for " ); 561 561 } … … 572 572 } 573 573 574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Node* deleter ) {574 void SymbolTable::addId( 575 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr, 576 const Decl * deleter ) { 577 577 ++*stats().add_calls; 578 578 const std::string &name = decl->name; … … 581 581 std::string mangleName; 582 582 if ( decl->linkage.is_overrideable ) { 583 // mangle the name without including the appropriate suffix, so overridable routines 583 // mangle the name without including the appropriate suffix, so overridable routines 584 584 // are placed into the same "bucket" as their user defined versions. 585 585 mangleName = Mangle::mangle( decl, Mangle::Mode{ Mangle::NoOverrideable } ); … … 588 588 } 589 589 590 // this ensures that no two declarations with the same unmangled name at the same scope 590 // this ensures that no two declarations with the same unmangled name at the same scope 591 591 // both have C linkage 592 592 if ( decl->linkage.is_mangled ) { … … 596 596 } 597 597 } else { 598 // NOTE: only correct if name mangling is completely isomorphic to C 598 // NOTE: only correct if name mangling is completely isomorphic to C 599 599 // type-compatibility, which it may not be. 600 600 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 628 628 idTable = idTable->set( 629 629 name, 630 mangleTable->set( 631 mangleName, 630 mangleTable->set( 631 mangleName, 632 632 IdData{ existing->second, handleConflicts.deleter } ) ); 633 633 } … … 647 647 } 648 648 649 void SymbolTable::addMembers( 649 void SymbolTable::addMembers( 650 650 const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) { 651 651 for ( const Decl * decl : aggr->members ) { … … 655 655 const Type * t = dwt->get_type()->stripReferences(); 656 656 if ( auto rty = dynamic_cast<const ReferenceToType *>( t ) ) { 657 if ( ! dynamic_cast<const StructInstType *>(rty) 657 if ( ! dynamic_cast<const StructInstType *>(rty) 658 658 && ! dynamic_cast<const UnionInstType *>(rty) ) continue; 659 659 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; 660 660 const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost ); 661 addMembers( 661 addMembers( 662 662 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts ); 663 663 } … … 680 680 if ( ! decl.second.id->linkage.is_mangled && decl.first == mangleName ) return true; 681 681 } 682 682 683 683 return false; 684 684 }
Note: See TracChangeset
for help on using the changeset viewer.