Synopsis - Cross-Reference

File: /Synopsis/Parsers/Cxx/Lookup.cc
   1//
   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: