Synopsis - Cross-Reference
File: /Synopsis/Parsers/Cxx/Lookup.cc1// 2// Copyright (C) 2001 Stephen Davies 3// Copyright (C) 2001 Stefan Seefeld 4// All rights reserved. 5// Licensed to the public under the terms of the GNU LGPL (>= 2), 6// see the file COPYING for details. 7// 8 9#include <map> 10#include <typeinfo> 11#include <sstream> 12#include <algorithm> 13 14#include "Lookup.hh" 15#include "Builder.hh" 16#include "Types.hh" 17#include "Dictionary.hh" 18#include "Walker.hh" 19#include "ScopeInfo.hh" 20#include "TypeInfo.hh" 21#include "TypeIdFormatter.hh" 22#include "STrace.hh" 23 24//. Simplify names. Typically only used for accessing vectors and iterators 25using namespace Types; 26using namespace ASG; 27 28// 29// Class ScopeInfo 30// 31ScopeInfo::ScopeInfo(ASG::Scope* s) 32 : is_using(false) 33{ 34 scope_decl = s; 35 search.push_back(this); 36 dict = new Dictionary(); 37 access = ASG::Default; 38} 39 40// FIXME: why is there a using scope? 41ScopeInfo::ScopeInfo(ScopeInfo* s) 42 : is_using(true) 43{ 44 scope_decl = s->scope_decl; 45 dict = s->dict; 46} 47 48ScopeInfo::~ScopeInfo() 49{ 50 //if (is_using == false) 51 // delete dict; 52} 53 54int 55ScopeInfo::getCount(const std::string& name) 56{ 57 return ++nscounts[name]; 58} 59 60 61/////// FIXME: wtf is this doing here?? 62namespace 63{ 64//. This class is very similar to ostream_iterator, except that it works on 65//. pointers to types 66template <typename T> 67class ostream_ptr_iterator 68{ 69 std::ostream* out; 70 const char* sep; 71public: 72 ostream_ptr_iterator(std::ostream& o, const char* s) : out(&o), sep(s) 73 {} 74 ostream_ptr_iterator<T>& operator =(const T* value) 75 { 76 *out << *value; 77 if (sep) 78 *out << sep; 79 return *this; 80 } 81 ostream_ptr_iterator<T>& operator *() 82 { 83 return *this; 84 } 85 ostream_ptr_iterator<T>& operator ++() 86 { 87 return *this; 88 } 89 ostream_ptr_iterator<T>& operator ++(int) 90 { 91 return *this; 92 } 93}; 94} 95 96// defined in common.hh 97std::string join(const ScopedName& strs, const std::string& sep) 98{ 99 ScopedName::const_iterator iter = strs.begin(); 100 if (iter == strs.end()) 101 return ""; 102 std::string str = *iter++; 103 while (iter != strs.end()) 104 str += sep + *iter++; 105 return str; 106} 107 108//. Output operator for debugging 109std::ostream& operator << (std::ostream& o, TypeInfo& i) 110{ 111 TypeIdFormatter tf; 112 o << "[" << tf.format(i.type); 113 if (i.is_const) 114 o << " (const)"; 115 if (i.is_volatile) 116 o << " (volatile)"; 117 if (i.deref) 118 o << " " << i.deref << "*"; 119 o << "]"; 120 return o; 121} 122 123 124// 125// Struct Lookup::Private 126// 127 128#if 0 129struct Lookup::Private 130{ 131 //. A map of ASG::Scope's ScopeInfo objects 132 typedef std::map<ASG::Scope*, ScopeInfo*> ScopeMap; 133 ScopeMap map; 134 135 //. A map of name references 136 typedef std::map<ScopedName, std::vector<ASG::Reference> > RefMap; 137 RefMap refs; 138}; 139#endif 140 141// 142// Class Lookup 143// 144 145Lookup::Lookup(Builder* builder) 146{ 147 m_builder = builder; 148} 149 150Lookup::~Lookup() 151{ 152 // TODO Delete all ... 153 //delete m; 154} 155 156//. Finds or creates a cached Scope 157ScopeInfo* Lookup::find_info(ASG::Scope* decl) 158{ 159 return m_builder->find_info(decl); 160} 161 162ASG::Scope* Lookup::global() 163{ 164 return m_builder->global(); 165} 166 167ASG::Scope* Lookup::scope() 168{ 169 return m_builder->scope(); 170} 171 172// 173// Type Methods 174// 175 176//. Predicate class that is true if the object passed to the constructor is a 177//. type, as opposed to a modifier or a parametrized, etc 178class isType : public Types::Visitor 179{ 180 bool m_value; 181public: 182 //. constructor. Visits the given type thereby setting the value 183 isType(Types::Named* type) : m_value(false) 184 { 185 type->accept(this); 186 } 187 //. bool operator, returns the value determined by visitation during 188 //. construction 189 operator bool() 190 { 191 return m_value; 192 } 193 //. Okay 194 void visit_base(Types::Base*) 195 { 196 m_value = true; 197 } 198 //. Okay 199 void visit_unknown(Types::Unknown*) 200 { 201 m_value = true; 202 } 203 //. Okay if not a function declaration 204 void visit_declared(Types::Declared* type) 205 { 206 // Depends on what was declared: Everything but function is okay 207 if (dynamic_cast<ASG::Function*>(type->declaration())) 208 m_value = false; 209 else 210 m_value = true; 211 } 212 //. Okay if a template dependent arg 213 void visit_dependent(Types::Dependent*) 214 { 215 m_value = true; 216 } 217 //. Fallback: Not okay 218 void visit_type(Types::Type*) 219 { 220 m_value = false; 221 } 222}; 223 224// Public method to lookup a type 225Types::Named* Lookup::lookupType(const std::string& name, bool func_okay) 226{ 227 STrace trace("Lookup::lookupType(name, func_okay)"); 228 Types::Named* type = lookup(name, func_okay); 229 if (type) 230 return type; 231 // Not found, declare it unknown 232 //cout << "Warning: Name "<<name<<" not found in "<<m_filename<<endl; 233 ScopedName u_name; 234 u_name.push_back(name); 235 return m_builder->create_unknown(u_name); 236} 237 238// Private method to lookup a type in the current scope 239Types::Named* Lookup::lookup(const std::string& name, bool func_okay) 240{ 241 STrace trace("Lookup::lookup(name, func_okay)"); 242 const ScopeSearch& search = m_builder->scopeinfo()->search; 243 return lookup(name, search, func_okay); 244} 245 246//. Looks up the name in the scope of the given scope 247Types::Named* Lookup::lookupType(const std::string& name, ASG::Scope* decl) 248{ 249 STrace trace("Lookup::lookupType(name,scope)"); 250 ScopeInfo* scope = find_info(decl); 251 return lookup(name, scope->search); 252} 253 254class FunctionHeuristic 255{ 256 typedef std::vector<Types::Type*> v_Type; 257 typedef v_Type::iterator vi_Type; 258 typedef std::vector<ASG::Parameter*> v_Param; 259 typedef v_Param::iterator vi_Param; 260 261 v_Type m_args; 262 int cost; 263#ifdef DEBUG 264 265 STrace trace; 266public: 267 //. Constructor - takes arguments to match functions against 268 FunctionHeuristic(const v_Type& v) 269 : m_args(v), trace("FunctionHeuristic") 270 { 271 TypeIdFormatter tf; 272 std::ostringstream buf; 273 for (size_t index = 0; index < v.size(); index++) 274 { 275 if (index) 276 buf << ", "; 277 buf << tf.format(v[index]); 278 } 279 //buf << std::ends; 280 LOG("Function arguments: " << buf.str()); 281 } 282#else 283public: 284 //. Constructor - takes arguments to match functions against 285 FunctionHeuristic(const v_Type& v) 286 : m_args(v) 287 { } 288#endif 289 290 //. Heuristic operator, returns 'cost' of given function - higher is 291 //. worse, 1000 means no match 292 int operator ()(ASG::Function* func) 293 { 294 cost = 0; 295 int num_args = m_args.size(); 296 v_Param* params =& func->parameters(); 297 bool func_ellipsis = hasEllipsis(params); 298 int num_params = params->size() - func_ellipsis; 299 int num_default = countDefault(params); 300 301 // Check number of params first 302 if (!func_ellipsis && num_args > num_params) 303 cost = 1000; 304 if (num_args < num_params - num_default) 305 cost = 1000; 306 307 if (cost < 1000) 308 { 309 // Now calc cost of each argument in turn 310 int max_arg = num_args > num_params ? num_params : num_args; 311 for (int index = 0; index < max_arg; index++) 312 calcCost(m_args[index], (*params)[index]->type()); 313 } 314 315#ifdef DEBUG 316 LOG("Function: " << func->name() << " -- Cost is " << cost); 317#endif 318 319 return cost; 320 } 321 322private: 323 //. Find an ellipsis as the lasg arg 324 bool hasEllipsis(v_Param* params) 325 { 326 if (params->size() == 0) 327 return false; 328 Types::Type* back = params->back()->type(); 329 if (Types::Base* base = dynamic_cast<Types::Base*>(back)) 330 if (base->name().size() == 1 && base->name().front() == "...") 331 return true; 332 return false; 333 } 334 335 //. Returns the number of parameters with default values. Counts from the 336 //. back and stops when it finds one without a default. 337 int countDefault(v_Param* params) 338 { 339 v_Param::reverse_iterator iter = params->rbegin(), end = params->rend(); 340 int count = 0; 341 while (iter != end) 342 { 343 ASG::Parameter* param = *iter++; 344 if (!param->value().size()) 345 break; 346 count++; 347 } 348 return count; 349 } 350 351 //. Calculate the cost of converting 'arg' into 'param'. The cost is 352 //. accumulated on the 'cost' member variable. 353 void calcCost(Types::Type* arg_t, Types::Type* param_t) 354 { 355 TypeIdFormatter tf; 356 if (!arg_t) 357 return; 358 TypeInfo arg(arg_t), param(param_t); 359#ifdef DEBUG 360 // std::cout << arg << param << std::endl; 361 // // std::cout << tf.format(type) <<","<<tf.format(param_type) << std::endl; 362#endif 363 // Null types convert to any ptr with no cost 364 if (arg.is_null && param.deref > 0) 365 return; 366 // Different types is bad 367 if (arg.type != param.type) 368 cost += 10; 369 // Different * levels is also bad 370 if (arg.deref != param.deref) 371 cost += 10; 372 // Worse constness is bad 373 if (arg.is_const > param.is_const) 374 cost += 5; 375 } 376}; 377 378//. Looks up the function in the given scope with the given args. 379ASG::Function* Lookup::lookupFunc(const std::string& name, ASG::Scope* decl, const std::vector<Types::Type*>& args) 380{ 381 STrace trace("Lookup::lookupFunc"); 382 TypeIdFormatter tf; 383 // Now loop over the search scopes 384 const ScopeSearch& search = find_info(decl)->search; 385 ScopeSearch::const_iterator s_iter = search.begin(); 386 typedef std::vector<ASG::Function*> v_Function; 387 v_Function functions; 388 389 // Loop over precalculated search list 390 while (s_iter != search.end()) 391 { 392 ScopeInfo* scope = *s_iter++; 393 394 // Check if dict has it 395 if (scope->dict->has_key(name)) 396 { 397 findFunctions(name, scope, functions); 398 } 399 // If not a dummy scope, resolve the set 400 if (scope->is_using == false && !functions.empty()) 401 { 402 // Return best function (or throw error) 403 int cost; 404 ASG::Function* func = bestFunction(functions, args, cost); 405 if (cost < 1000) 406 return func; 407 throw ERROR("No appropriate function found."); 408 } 409 } 410 411 throw ERROR("No matching functions found."); 412} 413 414// Operator lookup 415ASG::Function* Lookup::lookupOperator(const std::string& oper, Types::Type* left_type, Types::Type* right_type) 416{ 417 STrace trace("Lookup::lookupOperator("+oper+",left,right)"); 418 // Find some info about the two types 419 TypeInfo left(left_type), right(right_type); 420 bool left_user = !!dynamic_cast<Types::Declared*>(left_type) && !left.deref; 421 bool right_user = !!dynamic_cast<Types::Declared*>(right_type) && !right.deref; 422 423 // First check if the types are user-def or enum 424 if (!left_user && !right_user) 425 return 0; 426 427 std::vector<ASG::Function*> functions; 428 std::vector<Types::Type*> args; 429 ASG::Function* best_method = 0, *best_func = 0; 430 int best_method_cost, best_func_cost; 431 432 // Member methods of left_type 433 try 434 { 435 ASG::Class* clas = Types::declared_cast<ASG::Class>(left.type); 436 // Construct the argument list 437 args.push_back(right_type); 438 439 try 440 { 441 findFunctions(oper, find_info(clas), functions); 442 443 best_method = bestFunction(functions, args, best_method_cost); 444 } 445 catch (const Dictionary::KeyError&) 446 { 447 best_method = 0; 448 } 449 450 // Clear functions and args for use below 451 functions.clear(); 452 args.clear(); 453 } 454 catch (const Types::wrong_type_cast&) 455 { /* ignore: not a class */ 456 } 457 458 // Non-member functions 459 // Loop over the search scopes 460 const ScopeSearch& search = m_builder->scopeinfo()->search; 461 ScopeSearch::const_iterator s_iter = search.begin(); 462 while (s_iter != search.end()) 463 { 464 ScopeInfo* scope = *s_iter++; 465 // Check if dict has any names that match 466 if (!scope->dict->has_key(oper)) 467 continue; 468 469 // Get the matching functions from the dictionary 470 findFunctions(oper, scope, functions); 471 472 // Scope rules say once you find any results: stop 473 break; 474 } 475 476 // Koenig Rule: add operators from namespaces of arguments 477 // void findKoenigFunctions(oper, functions, args); 478 if (left_user) 479 try 480 { 481 ScopedName enclosing_name = Types::type_cast<Types::Named>(left.type)->name(); 482 enclosing_name.pop_back(); 483 if (enclosing_name.size()) 484 { 485 ScopeInfo* scope = find_info( Types::declared_cast<ASG::Scope>(lookupType(enclosing_name, false, global())) ); 486 findFunctions(oper, scope, functions); 487 } 488 } 489 catch (const Types::wrong_type_cast& e) 490 {} 491 492 if (right_user) 493 try 494 { 495 ScopedName enclosing_name = Types::type_cast<Types::Named>(right.type)->name(); 496 enclosing_name.pop_back(); 497 if (enclosing_name.size()) 498 { 499 ScopeInfo* scope = find_info( Types::declared_cast<ASG::Scope>(lookupType(enclosing_name, false, global())) ); 500 findFunctions(oper, scope, functions); 501 } 502 } 503 catch (const Types::wrong_type_cast& e) 504 {} 505 506 // Add builtin operators to aide in best-function resolution 507 // NYI 508 509 // Puts left and right types into args 510 args.push_back(left_type); 511 args.push_back(right_type); 512 // Find best non-method function 513 best_func = bestFunction(functions, args, best_func_cost); 514 515 // Return best method or function 516 if (best_method) 517 { 518 if (best_func) 519 { 520 if (best_func_cost < best_method_cost) 521 return best_func; 522 else 523 return best_method; 524 } 525 else 526 { 527 return best_method; 528 } 529 } 530 else 531 { 532 if (best_func) 533 return best_func; 534 else 535 return 0; 536 } 537} 538 539void Lookup::findFunctions(const std::string& name, ScopeInfo* scope, ASG::Function::vector& functions) 540{ 541 STrace trace("Lookup::findFunctions"); 542 543 // Get the matching names from the dictionary 544 try 545 { 546 Named::vector types = scope->dict->lookupMultiple(name); 547 548 // Put only the ASG::Functions into 'functions' 549 for (Named::vector::iterator iter = types.begin(); iter != types.end();) 550 try 551 { 552 functions.push_back( Types::declared_cast<ASG::Function>(*iter++) ); 553 } 554 catch (const Types::wrong_type_cast& ) 555 { 556 throw ERROR("looked up func '"<<name<<"'wasnt a func!"); 557 } 558 } 559 catch (Dictionary::KeyError) 560 { } 561} 562 563ASG::Function* Lookup::bestFunction(const ASG::Function::vector& functions, const Types::Type::vector& args, int& cost) 564{ 565 // Quick sanity check 566 if (!functions.size()) 567 return 0; 568 // Find best function using a heuristic 569 FunctionHeuristic heuristic(args); 570 Function::vector::const_iterator iter = functions.begin(), end = functions.end(); 571 ASG::Function* best_func = *iter++; 572 int best = heuristic(best_func); 573 while (iter != end) 574 { 575 ASG::Function* func = *iter++; 576 int cost = heuristic(func); 577 if (cost < best) 578 { 579 best = cost; 580 best_func = func; 581 } 582 } 583 cost = best; 584 return best_func; 585} 586 587// Private method to lookup a type in the specified search space 588Types::Named* Lookup::lookup(const std::string& name, const ScopeSearch& search, bool func_okay) throw () 589{ 590 STrace trace("Lookup::lookup(name,search,func_okay)"); 591 ScopeSearch::const_iterator s_iter = search.begin(); 592 Named::vector results; 593 while (s_iter != search.end()) 594 { 595 ScopeInfo* scope = *s_iter++; 596 // Check if dict has it 597 if (scope->dict->has_key(name)) 598 { 599 if (results.empty()) 600 results = scope->dict->lookupMultiple(name); 601 else 602 { 603 Named::vector temp_result = scope->dict->lookupMultiple(name); 604 std::copy(temp_result.begin(), temp_result.end(), 605 std::back_inserter(results)); 606 } 607 } 608 // If not a dummy scope, resolve the set 609 if (scope->is_using == false && !results.empty()) 610 { 611#ifdef DEBUG 612 Named::vector save_results = results; 613#endif 614 // Remove the unknowns 615 Types::Unknown* unknown = 0; 616 Named::vector::iterator r_iter = results.begin(); 617 while (r_iter != results.end()) 618 if ((unknown = dynamic_cast<Types::Unknown*>(*r_iter)) != 0) 619 r_iter = results.erase(r_iter); 620 else if (!func_okay && !isType(*r_iter)) 621 r_iter = results.erase(r_iter); 622 else 623 ++r_iter; 624 // Should be either 1 non-unknowns left or nothing but with 625 // 'unknown' set 626 if (results.size() == 0 && unknown != 0) 627 return unknown; 628 if (results.size() == 0) 629 // This means there was only functions in the list, which we are 630 // ignoring 631 continue; 632 if (results.size() == 1) 633 { 634 // Exactly one match! return it 635 Types::Named* type = results[0]; 636 Types::Declared* d = dynamic_cast<Types::Declared* >(type); 637 if (d) 638 { 639 ASG::UsingDeclaration *u = dynamic_cast<ASG::UsingDeclaration*>(d->declaration()); 640 if (u) type = u->target(); 641 } 642 return type; 643 } 644 // Store in class var? 645 LOG("Multiple candidates!"); 646#ifdef DEBUG 647 648 for (r_iter = save_results.begin(); r_iter != save_results.end(); ++r_iter) 649 LOG(" - '" << (*r_iter)->name() << "' - " << typeid(**r_iter).name()); 650#endif 651 Types::Named* type = results[0]; 652 // If we are looking at a 'declared' UsingDeclaration, return the referenced target. 653 Types::Declared* d = dynamic_cast<Types::Declared* >(type); 654 if (d) 655 { 656 ASG::UsingDeclaration *u = dynamic_cast<ASG::UsingDeclaration*>(d->declaration()); 657 if (u) type = u->target(); 658 } 659 return type; 660 } 661 } 662 return 0; 663} 664 665class InheritanceAdder 666{ 667 std::list<ASG::Class*>& open_list; 668public: 669 InheritanceAdder(std::list<ASG::Class*>& l) : open_list(l) 670 {} 671 InheritanceAdder(const InheritanceAdder& i) : open_list(i.open_list) 672 {} 673 void operator() (ASG::Inheritance* i) 674 { 675 try 676 { 677 ASG::Class* parent = Types::declared_cast<ASG::Class>(i->parent()); 678 open_list.push_back(parent); 679 } 680 catch (const Types::wrong_type_cast&) 681 { 682 // ?? ignore for now 683 } 684 } 685}; 686 687//. Private Qualified type lookup 688Types::Named* Lookup::lookupQual(const std::string& name, const ScopeInfo* scope, bool func_okay) 689{ 690 STrace trace("Lookup::lookupQual"); 691 //LOG("name: " << name << " in: " << scope->scope_decl->name()); 692 // First determine: class or namespace 693 if (ASG::Class* the_class = dynamic_cast<ASG::Class*>(scope->scope_decl)) 694 { 695 // A class: search recursively, in order, through base classes 696 // FIXME: read up about overriding, hiding, virtual bases and funcs, 697 // etc 698 std::list<ASG::Class*> open_list; 699 open_list.push_back(the_class); 700 while (!open_list.empty()) 701 { 702 ASG::Class* clas = open_list.front(); 703 open_list.pop_front(); 704 ScopeInfo* scope = find_info(clas); 705 if (scope->dict->has_key(name)) 706 { 707 try 708 { 709 Types::Named* named = scope->dict->lookup(name); 710 if (func_okay || isType(named)) 711 { 712 return named; 713 } 714 // Else it's a function and a type was wanted: keep looking 715 } 716 catch (const Dictionary::MultipleError& e) 717 { 718 // FIXME: check for duplicates etc etc 719 } 720 catch (const Dictionary::KeyError& e) 721 { 722 std::cerr << "Warning: Key error when has_key said yes" << std::endl; 723 } 724 } 725 // Add base classes to open list 726 std::for_each(clas->parents().begin(), clas->parents().end(), 727 InheritanceAdder(open_list)); 728 } 729 } 730 else if (dynamic_cast<ASG::Namespace*>(scope->scope_decl)) 731 { 732 // A namespace: search recursively through using declarations 733 // constructing a conflict set - dont traverse using declarations of 734 // any namespace which has an entry for 'name'. Each NS only once 735 std::list<const ScopeInfo*> open, closed; 736 open.push_back(scope); 737 std::vector<Types::Named*> results; 738 while (!open.empty()) 739 { 740 const ScopeInfo* ns = open.front(); 741 open.pop_front(); 742 // Check if 'ns' is on closed list 743 if (std::find(closed.begin(), closed.end(), ns) != closed.end()) 744 continue; 745 // Add to closed list 746 closed.push_back(ns); 747 // Check if 'ns' has 'name' 748 if (ns->dict->has_key(name)) 749 { 750 // Add all results to results list 751 if (results.empty()) 752 results = ns->dict->lookupMultiple(name); 753 else 754 { 755 std::vector<Types::Named*> temp = ns->dict->lookupMultiple(name); 756 std::copy(temp.begin(), temp.end(), 757 back_inserter(results)); 758 } 759 } 760 else 761 { 762 // Add 'using' Scopes to open list 763 std::copy(ns->using_scopes.begin(), ns->using_scopes.end(), 764 back_inserter(open)); 765 } 766 } 767 // Now we have a set of results 768 if (!results.size()) 769 { 770 LOG("No results! Looking up '" << name << "'"); 771 return 0; 772 } 773 // FIXME: figure out what to do about multiple 774 Types::Named* best = 0; 775 int best_score = -1; 776 for (std::vector<Types::Named*>::iterator iter = results.begin(); 777 iter != results.end(); iter++) 778 { 779 // Fixme.. create a Score visitor 780 int score = 0; 781 Types::Named* type = *iter; 782 if (Types::Declared* declared = dynamic_cast<Types::Declared*>(type)) 783 { 784 score++; 785 if (ASG::Declaration* decl = declared->declaration()) 786 { 787 score++; 788 if (dynamic_cast<ASG::Forward*>(decl)) 789 score--; 790 } 791 } 792 if (score > best_score) 793 { 794 best_score = score; 795 best = type; 796 } 797 } 798 799 return best; 800 } 801 // Not class or NS - which is illegal for a qualified (but coulda been 802 // template etc?:) 803 LOG("Not class or namespace: " << typeid(scope->scope_decl).name()); 804 return 0; 805} 806 807//. Public Qualified Type Lookup 808Types::Named* Lookup::lookupType(const std::vector<std::string>& names, bool func_okay, ASG::Scope* start_scope) 809{ 810 STrace trace("Lookup::lookupType(vector names,search,func_okay)"); 811 //LOG("looking up '" << names << "' in " << (start_scope?start_scope->name() : m_scope->name())); 812 Types::Named* type = 0; 813 ScopeInfo* scope = 0; 814 std::vector<std::string>::const_iterator n_iter = names.begin(); 815 // Setup the initial scope 816 std::string name = *n_iter; 817 if (!name.size()) 818 { 819 // Qualified name starts with :: so always start at global scope 820 type = global()->declared(); 821 } 822 else 823 { 824 // Lookup first name as usual 825 if (start_scope) 826 type = lookupType(name, start_scope); 827 else 828 type = lookupType(name); 829 } 830 ++n_iter; 831 832 // Look over every identifier in the qualified name 833 while (n_iter != names.end()) 834 { 835 name = *n_iter++; 836 try 837 { 838 // FIXME: this should use some sort of visitor 839 ASG::Declaration* decl = Types::declared_cast<ASG::Declaration>(type); 840 if (ASG::Typedef* tdef = dynamic_cast<ASG::Typedef*>(decl)) 841 { 842 type = Types::type_cast<Types::Named>(tdef->alias()); 843 } 844 // FIXME: type can be a Types::Dependent (i.e. a template parameter) 845 // in which case this will throw a wrong_type_cast !!! 846 // Find cached scope from 'type' 847 scope = find_info( Types::declared_cast<ASG::Scope>(type) ); 848 } 849 catch (const Types::wrong_type_cast& ) 850 { 851 // Abort lookup 852 throw ERROR("qualified lookup found a type (" << type->name() << ") that wasn't a scope finding: " << names); 853 } 854 // Find the named type in the current scope 855 type = lookupQual(name, scope, func_okay && n_iter == names.end()); 856 if (!type) 857 // Abort lookup 858 break; 859 } 860 861 if (!type) 862 { 863 LOG("Not found -> creating Unknown"); 864 // Not found! Add Type.Unknown of scoped name 865 return m_builder->create_unknown(names); 866 } 867 return type; 868} 869 870//. Maps a scoped name into a vector of scopes and the final type. Returns 871//. true on success. 872bool Lookup::mapName(const ScopedName& names, std::vector<ASG::Scope*>& o_scopes, Types::Named*& o_type) 873{ 874 STrace trace("Lookup::mapName"); 875 ASG::Scope* asg_scope = global(); 876 ScopedName::const_iterator iter = names.begin(); 877 ScopedName::const_iterator lasg = names.end(); 878 lasg--; 879 ScopedName scoped_name; 880 881 // Start scope name at global level 882 scoped_name.push_back(""); 883 884 // Sanity check 885 if (iter == names.end()) 886 return false; 887 888 // Loop through all containing scopes 889 while (iter != lasg) 890 { 891 //const std::string& name = *iter++; 892 scoped_name.push_back(*iter++); 893 Types::Named* type = lookupType(scoped_name); 894 if (!type) 895 { 896 LOG("Warning: failed to lookup " << scoped_name << " in global scope"); 897 return false; 898 } 899 try 900 { 901 asg_scope = Types::declared_cast<ASG::Scope>(type); 902 } 903 catch (const Types::wrong_type_cast&) 904 { 905 LOG("Warning: looked up scope wasnt a scope!" << scoped_name); 906 return false; 907 } 908 o_scopes.push_back(asg_scope); 909 } 910 911 // iter now == lasg, which can be any type 912 scoped_name.push_back(*iter); 913 Types::Named* type = lookupType(scoped_name, true); 914 if (!type) 915 { 916 //find_info(asg_scope)->dict->dump(); 917 LOG("\nWarning: final type lookup wasn't found!" << *iter); 918 return false; 919 } 920 921 o_type = type; 922 return true; 923} 924 925Types::Type* Lookup::arrayOperator(Types::Type* object, Types::Type* arg, ASG::Function*& func_oper) 926{ 927 STrace trace("Lookup::arrayOperator"); 928 func_oper = 0; 929 // First decide if should use derefence or methods 930 TypeInfo info(object); 931 if (info.deref) 932 { 933 // object is of pointer type, so just deref it 934 // Check for typedef 935 try 936 { 937 object = Types::declared_cast<ASG::Typedef>(object)->alias(); 938 } 939 catch (const Types::wrong_type_cast&) 940 { /* ignore -- not a typedef */ 941 } 942 // Check for modifier 943 if (Types::Modifier* mod = dynamic_cast<Types::Modifier*>(object)) 944 { 945 typedef Types::Type::Mods Mods; 946 Types::Modifier* newmod = new Types::Modifier(mod->alias(), mod->pre(), mod->post()); 947 for (Mods::iterator iter = newmod->post().begin(); iter != newmod->post().end(); iter++) 948 { 949 if (*iter == "*" || *iter == "[]") 950 { 951 newmod->post().erase(iter); 952 return newmod; 953 } 954 } 955 //delete newmod; 956 throw ERROR("Unable to dereference type for array operator!"); 957 } 958 throw ERROR("Unknown type for array operator!"); 959 } 960 961 // Hmm object type -- try for [] method 962 ASG::Class* clas; 963 try 964 { 965 clas = Types::declared_cast<ASG::Class>(info.type); 966 } 967 catch (const Types::wrong_type_cast&) 968 { 969 TypeIdFormatter tf; 970 throw ERROR("Not deref and not class type for array operator! " << tf.format(info.type) << " <-- " << tf.format(object)); 971 } 972 973 Function::vector functions; 974 try 975 { 976 findFunctions("[]", find_info(clas), functions); 977 } 978 catch (const Dictionary::KeyError&) 979 { 980 throw ERROR("No array operator for class " << clas->name()); 981 } 982 983 // Make args list 984 std::vector<Types::Type*> args; 985 args.push_back(arg); 986 987 // Find best function 988 int cost; 989 ASG::Function* func = bestFunction(functions, args, cost); 990 if (!func || cost >= 1000) 991 throw ERROR("No best function found for array operator."); 992 func_oper = func; 993 return func->return_type(); 994} 995 996Types::Named* Lookup::resolveType(Types::Named* type) 997{ 998 STrace trace("Lookup::resolveType(named)"); 999 try 1000 { 1001 ScopedName& name = type->name(); 1002 LOG("Resolving '" << name << "'"); 1003 1004 ScopedName::iterator iter = name.begin(), end = name.end() - 1; 1005 ASG::Scope* scope = global(); 1006 while (iter != end) 1007 { 1008 // Find *iter in scope 1009 Types::Named* scope_type = find_info(scope)->dict->lookup(*iter++); 1010 scope = Types::declared_cast<ASG::Scope>(scope_type); 1011 } 1012 LOG("Looking up '"<<(*iter)<<"' in '"<< ((scope==global())?"global":scope->name().back()) << "'"); 1013 // Scope is now the containing scope of the type we are checking 1014 return find_info(scope)->dict->lookup(*iter); 1015 } 1016 catch (const Types::wrong_type_cast& ) 1017 { 1018 LOG("resolveType failed! bad cast."); 1019 } 1020 catch (Dictionary::KeyError e) 1021 { 1022 LOG("resolveType failed! key error: '"<<e.name<<"'"); 1023 } 1024 catch (Dictionary::MultipleError e) 1025 { 1026 LOG("resolveType failed! multiple:" << e.types.size()); 1027 std::vector<Types::Named*>::iterator iter = e.types.begin(); 1028 while (iter != e.types.end()) 1029 { 1030 LOG(" +" << (*iter)->name()); 1031 iter++; 1032 } 1033 } 1034 catch (...) 1035 { 1036 // There shouldn't be any errors, but just in case... 1037 throw ERROR("resolveType failed with unknown error!"); 1038 } 1039 return type; 1040} 1041 1042std::string Lookup::dumpSearch(ScopeInfo* scope) 1043{ 1044 ScopeSearch& search = scope->search; 1045 std::ostringstream buf; 1046 buf << "Search for "; 1047 if (scope->scope_decl->name().size() == 0) 1048 buf << "global"; 1049 else 1050 buf << this->scope()->name(); 1051 buf << " is now: "; 1052 ScopeSearch::iterator iter = search.begin(); 1053 while (iter != search.end()) 1054 { 1055 buf << (iter==search.begin() ? "" : ", "); 1056 const ScopedName& name = (*iter)->scope_decl->name(); 1057 if (name.size()) 1058 if ( (*iter)->is_using ) 1059 buf << "(" << name << ")"; 1060 else 1061 buf << name; 1062 else 1063 buf << "global"; 1064 ++iter; 1065 } 1066 //buf << std::ends; 1067 return buf.str(); 1068} 1069 1070 1071// vim: set ts=8 sts=4 sw=4 et: