Changeset 0ac366b for src/SymTab/Indexer.cc
- Timestamp:
- Feb 15, 2018, 11:39:12 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 4a161be
- Parents:
- f5883bd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Indexer.cc
rf5883bd r0ac366b 286 286 } 287 287 288 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {289 if ( ! tables ) return 0;290 if ( tables->scope < scope ) return 0;288 const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 289 if ( ! tables ) return nullptr; 290 if ( tables->scope < scope ) return nullptr; 291 291 292 292 IdTable::const_iterator decls = tables->idTable.find( id ); … … 294 294 const MangleTable &mangleTable = decls->second; 295 295 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 296 if ( decl != mangleTable.end() ) return decl->second.id;296 if ( decl != mangleTable.end() ) return &decl->second; 297 297 } 298 298 299 299 return tables->base.lookupIdAtScope( id, mangleName, scope ); 300 } 301 302 Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) { 303 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope )); 300 304 } 301 305 … … 373 377 } 374 378 375 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added) {379 bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) { 376 380 // if we're giving the same name mangling to things of different types then there is something wrong 377 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )378 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );379 380 if ( LinkageSpec::isOverridable( existing ->get_linkage() ) ) {381 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing.id ) ) 382 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing.id ) ) ); 383 384 if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) { 381 385 // new definition shadows the autogenerated one, even at the same scope 382 386 return false; 383 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 387 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) { 388 389 // it is a conflict if one declaration is deleted and the other is not 390 if ( deleteStmt && ! existing.deleteStmt ) { 391 return handleConflicts( existing, "deletion of defined identifier " ); 392 } else if ( ! deleteStmt && existing.deleteStmt ) { 393 return handleConflicts( existing, "definition of deleted identifier " ); 394 } 395 384 396 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 385 397 // we should ignore outermost pointer qualifiers, except _Atomic? 386 FunctionDecl * newentry = dynamic_cast< FunctionDecl* >( added );387 FunctionDecl * oldentry = dynamic_cast< FunctionDecl* >( existing);398 FunctionDecl * newentry = dynamic_cast< FunctionDecl * >( added ); 399 FunctionDecl * oldentry = dynamic_cast< FunctionDecl * >( existing.id ); 388 400 if ( newentry && oldentry ) { 389 401 if ( newentry->get_statements() && oldentry->get_statements() ) { 390 throw SemanticError( "duplicate function definition for ", added);402 return handleConflicts( existing, "duplicate function definition for " ); 391 403 } // if 392 404 } else { … … 395 407 // xxx - perhaps it's actually if either is intrinsic then this is okay? 396 408 // might also need to be same storage class? 397 ObjectDecl * newobj = dynamic_cast< ObjectDecl* >( added );398 ObjectDecl * oldobj = dynamic_cast< ObjectDecl* >( existing);409 ObjectDecl * newobj = dynamic_cast< ObjectDecl * >( added ); 410 ObjectDecl * oldobj = dynamic_cast< ObjectDecl * >( existing.id ); 399 411 if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) { 400 throw SemanticError( "duplicate object definition for ", added);412 return handleConflicts( existing, "duplicate object definition for " ); 401 413 } // if 402 414 } // if 403 415 } else { 404 throw SemanticError( "duplicate definition for ", added);416 return handleConflicts( existing, "duplicate definition for " ); 405 417 } // if 406 418 … … 408 420 } 409 421 410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr) {422 void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) { 411 423 if ( decl->name == "" ) return; 412 424 debugPrint( "Adding Id " << decl->name << std::endl ); … … 441 453 442 454 // Skip repeat declarations of the same identifier 443 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );444 if ( existing && addedIdConflicts( existing, decl) ) return;455 IdData * existing = lookupIdAtScope( name, mangleName, scope ); 456 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return; 445 457 446 458 // add to indexer 447 tables->idTable[ name ][ mangleName ] = { decl, baseExpr };459 tables->idTable[ name ][ mangleName ] = { decl, baseExpr, deleteStmt }; 448 460 ++tables->size; 461 } 462 463 void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) { 464 // default handling of conflicts is to raise an error 465 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, baseExpr ); 466 } 467 468 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) { 469 // default handling of conflicts is to raise an error 470 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, nullptr, deleteStmt ); 449 471 } 450 472 … … 573 595 } 574 596 575 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr ) {597 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) { 576 598 for ( Declaration * decl : aggr->members ) { 577 599 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 578 addId( dwt, expr );600 addId( dwt, handleConflicts, expr ); 579 601 if ( dwt->name == "" ) { 580 602 Type * t = dwt->get_type()->stripReferences(); … … 582 604 Expression * base = expr->clone(); 583 605 ResolvExpr::referenceToRvalueConversion( base ); 584 addMembers( t->getAggr(), new MemberExpr( dwt, base ) );606 addMembers( t->getAggr(), new MemberExpr( dwt, base ), handleConflicts ); 585 607 } 586 608 } … … 589 611 } 590 612 591 void Indexer::addWith( std::list< Expression * > & withExprs ) {613 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) { 592 614 for ( Expression * expr : withExprs ) { 593 615 if ( expr->result ) { … … 595 617 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 596 618 597 addMembers( aggr, expr ); 619 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) { 620 // on conflict, delete the identifier 621 existing.deleteStmt = withStmt; 622 return true; 623 }); 598 624 } 599 625 } … … 680 706 681 707 Expression * Indexer::IdData::combine() const { 708 Expression * ret = nullptr; 682 709 if ( baseExpr ) { 683 710 Expression * base = baseExpr->clone(); 684 711 ResolvExpr::referenceToRvalueConversion( base ); 685 Expression *ret = new MemberExpr( id, base );712 ret = new MemberExpr( id, base ); 686 713 // xxx - this introduces hidden environments, for now remove them. 687 714 // std::swap( base->env, ret->env ); 688 715 delete base->env; 689 716 base->env = nullptr; 690 return ret; 691 } else { 692 return new VariableExpr( id ); 693 } 717 } else { 718 ret = new VariableExpr( id ); 719 } 720 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt ); 721 return ret; 694 722 } 695 723 } // namespace SymTab
Note: See TracChangeset
for help on using the changeset viewer.