Synopsis - Cross-Reference

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