Synopsis - Cross-Reference
File: /Synopsis/Parsers/Cxx/TypeIdFormatter.cc1// 2// Copyright (C) 2008 Stefan Seefeld 3// All rights reserved. 4// Licensed to the public under the terms of the GNU LGPL (>= 2), 5// see the file COPYING for details. 6// 7 8#include "TypeIdFormatter.hh" 9 10TypeIdFormatter::TypeIdFormatter () 11 : fptr_id_(0) 12{ 13 scope_stack_.push_back(ScopedName()); 14} 15 16void TypeIdFormatter::push_scope(const ScopedName& scope) 17{ 18 scope_stack_.push_back(scope_); 19 scope_ = scope; 20} 21 22void TypeIdFormatter::pop_scope() 23{ 24 scope_ = scope_stack_.back(); 25 scope_stack_.pop_back(); 26} 27 28std::string TypeIdFormatter::colonate(const ScopedName& name) 29{ 30 std::string str; 31 ScopedName::const_iterator n = name.begin(); 32 ScopedName::const_iterator s = scope_.begin(); 33 // Skip identical scopes 34 while (n != name.end() && s != scope_.end() && *n == *s) ++n, ++s; 35 // If name == scope, just return last eg: struct S { S* ptr; }; 36 if (n == name.end()) 37 return name.back(); 38 // Join the rest in name with colons 39 str = *n++; 40 while (n != name.end()) 41 str += "::" + *n++; 42 return str; 43} 44 45std::string TypeIdFormatter::format(const Types::Type* type, const std::string** id) 46{ 47 if (!type) 48 return "(unknown)"; 49 const std::string** save = 0; 50 if (id) 51 { 52 save = fptr_id_; 53 fptr_id_ = id; 54 } 55 const_cast<Types::Type*>(type)->accept(this); 56 if (id) 57 fptr_id_ = save; 58 return type_; 59} 60 61void TypeIdFormatter::visit_type(Types::Type* type) 62{ 63 type_ = "(unknown)"; 64} 65 66void TypeIdFormatter::visit_unknown(Types::Unknown* type) 67{ 68 type_ = colonate(type->name()); 69} 70 71void TypeIdFormatter::visit_modifier(Types::Modifier* type) 72{ 73 // Premods 74 std::string pre = ""; 75 Types::Type::Mods::iterator iter = type->pre().begin(); 76 while (iter != type->pre().end()) 77 if (*iter == "*" || *iter == "&") 78 pre += *iter++; 79 else 80 pre += *iter++ + " "; 81 // Alias 82 type_ = pre + format(type->alias()); 83 // Postmods 84 iter = type->post().begin(); 85 while (iter != type->post().end()) 86 if (*iter == "*" || *iter == "&") 87 type_ += *iter++; 88 else 89 type_ += " " + *iter++; 90} 91 92void TypeIdFormatter::visit_named(Types::Named* type) 93{ 94 type_ = colonate(type->name()); 95} 96 97void TypeIdFormatter::visit_base(Types::Base* type) 98{ 99 type_ = colonate(type->name()); 100} 101 102void TypeIdFormatter::visit_declared(Types::Declared* type) 103{ 104 type_ = colonate(type->name()); 105} 106 107void TypeIdFormatter::visit_template_type(Types::Template* type) 108{ 109 type_ = colonate(type->name()); 110} 111 112void TypeIdFormatter::visit_parameterized(Types::Parameterized* type) 113{ 114 std::string str; 115 if (type->template_id()) 116 str = colonate(type->template_id()->name()) + "<"; 117 else 118 str = "(unknown)<"; 119 if (type->parameters().size()) 120 { 121 str += format(type->parameters().front()); 122 Types::Type::vector::iterator iter = type->parameters().begin(); 123 while (++iter != type->parameters().end()) 124 str += "," + format(*iter); 125 } 126 type_ = str + ">"; 127} 128 129void TypeIdFormatter::visit_func_ptr(Types::FuncPtr* type) 130{ 131 std::string str = format(type->return_type()) + "("; 132 Types::Type::Mods::iterator i_pre = type->pre().begin(); 133 while (i_pre != type->pre().end()) 134 str += *i_pre++; 135 if (fptr_id_) 136 { 137 str += **fptr_id_; 138 *fptr_id_ = 0; 139 } 140 str += ")("; 141 if (type->parameters().size()) 142 { 143 str += format(type->parameters().front()); 144 Types::Type::vector::iterator iter = type->parameters().begin(); 145 while (++iter != type->parameters().end()) 146 str += "," + format(*iter); 147 } 148 type_ = str + ")"; 149}