#include <fstream>
#include <iostream>
#include <cstdlib>
-#include "abg-ir.h"
-#include "abg-reader.h"
+#include "abg-dwarf-reader.h"
#include "test-utils.h"
using std::string;
using std::cerr;
using std::cout;
+///@file
+///
+/// This example shows how to walk the Internal Representation (IR)
+/// graph of the ABI of a binary (called an ABI Corpus) and perform
+/// actions on each node of the graph.
+///
+/// Basically, one has to define a "visitor" which carries member
+/// functions that are called during the traversal of the graph.
+///
+/// On the visitor, there is potentially one member function pair per
+/// type of node traversed. Each time a given node is visited, the
+/// corresponding member function pair is called by the traversal
+/// machinery. In other words, the visitor is notified each time a
+/// node is traversed.
+///
+/// To define a visitor, one has to create a type which implements
+/// (inherits) the abigail::ir_node_visitor interface. The visitor
+/// must have a pair of node_begin() and node_end() function per type
+/// of node that we wish to be notified for.
+///
+/// Once the visitor is defined, we can load an elf file and build an
+/// ABI corpus out of it by using the
+/// libabigail::dwarf_reader::read_corpus_from_elf() function, for
+/// instance.
+///
+/// Then we enumerate the translation units comprised in
+/// that ABI corpus and we invoke their "traverse()" method, using
+/// and instance of the visitor that we just defined.
+///
+/// Enjoy!
+
struct name_printing_visitor : public abigail::ir_node_visitor
{
unsigned level_;
string file_name = argv[1];
abigail::ir::environment_sptr env(new abigail::ir::environment);
- abigail::translation_unit_sptr tu;
- if (!(tu = abigail::xml_reader::read_translation_unit_from_file(file_name,
- env.get())))
+ abigail::corpus_sptr c;
+ abigail::dwarf_reader::status status = abigail::dwarf_reader::STATUS_OK;
+ if (!(c = abigail::dwarf_reader::read_corpus_from_elf(file_name,
+ /*debug_info_path=*/0,
+ env.get(),
+ /*load_all_type=*/false,
+ status)))
{
cerr << "failed to read " << file_name << "\n";
return 1;
}
name_printing_visitor v;
- tu->traverse(v);
+ // Now traverse each translation unit of the corpus using our
+ // instance of name_printing_visitor
+ for (abigail::ir::translation_units::const_iterator tu_iterator =
+ c->get_translation_units().begin();
+ tu_iterator != c->get_translation_units().end();
+ ++tu_iterator)
+ (*tu_iterator)->traverse(v);
}