print_types.cpp

Coverity Documentation

Version
latest
// print type information for every local variable
#include "extend-lang.hpp"   // Extend API
#include <string>            // std::string
#include <set>               // std::set
using namespace types;
using namespace std;
// set of classes whose info has been printed
set<string> printedClasses;
// type_recurisve_visitor_t is defined in extend-types.hpp
class ClassTypePrinter : public type_recursive_visitor_t {
public:
  virtual void on_class(const class_type_t &ct);
};
void ClassTypePrinter::on_class(const class_type_t &c)
{
  defined_class_type_t ct = c.load_definition();
  if (!ct) {
    return;
  }
  // obtain qualified name as a string, e.g., "A::B::C"
  ostringstream os;
  os << ct;
  string name = os.str();
  // check to see if we've already printed it
  if (printedClasses.find(name) != printedClasses.end()) {
    return;
  }
  printedClasses.insert(name);
  // print class/struct name
  cout << name << endl;
  // print what this class inherits from
  foreach(p, ct->get_parents()) {
    cout << "  parent: " << p->get_class() << endl;
  }
  // print fields
  foreach(f, ct->get_fields()) {
    cout << "  field: " << (*f)->get_pretty_name()
         << ", type: " << (*f)->get_type() << endl;
  }
  // re-examine field types, looking for classes to print; do this
  // after the above loop so we don't get fields from different
  // classes mixed together
  foreach(f, ct->get_fields()) {
    (*f)->get_type()->visit(*this);
  }
  // similarly for parent classes
  foreach(p, ct->get_parents()) {
    p->get_class()->visit(*this);
  }
}
void printVarInfo(const Expression* varTree)
{
  if (!varTree) {
    return;
  }
  type_t const *t = get_type_of_tree(varTree);
  if (!t) {
    return;
  }
  cout << "local variable:\n"
       << "  file: " << current_file_get_name() << "\n"
       << "  line: " << current_file_lineno() << "\n"
       << "  function: " << current_function_get_name() << "\n"
       << "  var: " << varTree << "\n"
       << "  type: " << *t << endl;
  // visit all the types in 't', looking for classes to print
  ClassTypePrinter ctp;
  ctp(t);
}
START_EXTEND_CHECKER( print_types, simple );
ANALYZE_TREE()
{
  Decl decl;
  if (MATCH(decl)) {
    printVarInfo(decl.var());
  }
}
END_EXTEND_CHECKER();
MAKE_MAIN( print_types )