Synopsis - Cross-Reference
File: /Synopsis/Parsers/Cxx/Dictionary.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 "Dictionary.hh" 10#include "ASG.hh" 11#include "Types.hh" 12 13#include <map> 14#include <vector> 15#include <list> 16#include <string> 17#include <iostream> 18#include <cassert> 19 20typedef std::multimap<std::string, Types::Named*> name_map; 21 22//. Define nested class 23struct Dictionary::Data 24{ 25 name_map map; 26}; 27 28//. Constructor 29Dictionary::Dictionary() 30{ 31 m = new Data; 32} 33 34//. Destructor 35Dictionary::~Dictionary() 36{ 37 delete m; 38} 39 40//. Quick check if the name is in the dict 41bool 42Dictionary::has_key(const std::string& name) 43{ 44 return m->map.find(name) != m->map.end(); 45} 46 47//. Lookup single 48//. TODO: the forward filtering could probably be done much simpler! 49//. TODO: The exception throwing is heavy too, besides all the vector copying! 50Types::Named* 51Dictionary::lookup(const std::string& name) 52{ 53 name_map::iterator iter = m->map.lower_bound(name); 54 name_map::iterator end = m->map.upper_bound(name); 55 56 // Check for not found 57 if (iter == end) 58 throw KeyError(name); 59 60 Types::Named* type = iter->second; 61 if (++iter == end) 62 return type; 63 64 // Check for Unknown types 65 if (dynamic_cast<Types::Unknown*>(type)) 66 { 67 // Skip further unknown types 68 while (iter != end && dynamic_cast<Types::Unknown*>(iter->second)) 69 ++iter; 70 if (iter == end) 71 // No choice but to return the Unknown 72 return type; 73 type = (iter++)->second; 74 // Any other types that aren't unknown cause error 75 while (iter != end && dynamic_cast<Types::Unknown*>(iter->second)) 76 ++iter; 77 if (iter == end) 78 // No more non-Unknown types, so return the one we found 79 return type; 80 } 81 // Create exception object 82 MultipleError exc(name); 83 exc.types.push_back(type); 84 do 85 exc.types.push_back(iter->second); 86 while (++iter != end); 87 throw exc; 88} 89 90//. Lookup multiple 91std::vector<Types::Named*> 92Dictionary::lookupMultiple(const std::string& name) throw (KeyError) 93{ 94 name_map::iterator iter = m->map.lower_bound(name); 95 name_map::iterator end = m->map.upper_bound(name); 96 97 // Check for not found 98 if (iter == end) 99 throw KeyError(name); 100 101 // Store type pointers in a vector 102 std::vector<Types::Named*> types; 103 do 104 types.push_back(iter->second); 105 while (++iter != end); 106 return types; 107} 108 109void 110Dictionary::insert(Types::Named* type) 111{ 112 std::string key = type->name().back(); 113 m->map.insert(name_map::value_type(key, type)); 114} 115 116void 117Dictionary::insert(ASG::Declaration* decl) 118{ 119 Types::Declared* declared = new Types::Declared(decl->name(), decl); 120 insert(declared); 121 if (ASG::Function* func = dynamic_cast<ASG::Function*>(decl)) 122 // Also insert real (unmangled) name of functions 123 m->map.insert(name_map::value_type(func->realname(), declared)); 124} 125 126void 127Dictionary::dump() 128{ 129 name_map::iterator iter = m->map.begin(), end = m->map.end(); 130 std::cout << "Dumping dictionary: " << m->map.size() << " items.\n"; 131 while (iter != end) 132 { 133 name_map::value_type p = *iter++; 134 std::cout << " " << p.first << "\t-> " << p.second->name() << "\n"; 135 } 136 std::cout.flush(); 137} 138// vim: set ts=8 sts=4 sw=4 et: