Make tree walking preemptive

* include/abg-traverse.h (traversable_base::traversable): Change
	the signature of this to return a boolean.
	* include/abg-ir.h (ir_traversable_base::traverse): Change the
	signature of this to return a boolean.
	(*::traverse): Adjust.
	(ir_node_visitor::visit): Change the signature of this to return a
	boolean.
	* src/abg-corpus.cc (symtab_build_visitor_type::visit): Adjust.
	* src/abg-ir.cc (::traverse): Adjust.
	* tests/test-walker.cc (name_printing_visitor::visit): Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2014-03-19 11:01:58 +01:00
parent 12b78c366d
commit 88741744e7
6 changed files with 224 additions and 123 deletions

View File

@ -118,8 +118,14 @@ typedef shared_ptr<ir_traversable_base> ir_traversable_base_sptr;
/// to be traversed.
struct ir_traversable_base : public traversable_base
{
virtual void
traverse(ir_node_visitor&);
/// Traverse a given IR node and its children, calling an visitor on
/// each node.
///
/// @param v the visitor to call on each traversed node.
///
/// @return true if the all the IR node tree was traversed.
virtual bool
traverse(ir_node_visitor& v);
}; // end class ir_traversable_base
/// This is the abstraction of the set of relevant artefacts (types,
@ -171,7 +177,7 @@ public:
bool
operator==(const translation_unit&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
};//end class translation_unit
@ -338,7 +344,7 @@ public:
virtual bool
operator==(const decl_base&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~decl_base();
@ -531,7 +537,7 @@ public:
bool
find_iterator_for_member(const decl_base_sptr, declarations::iterator&);
virtual void
virtual bool
traverse(ir_node_visitor&);
virtual ~scope_decl();
@ -693,7 +699,7 @@ public:
virtual string
get_pretty_representation() const;
virtual void
virtual bool
traverse(ir_node_visitor&);
virtual ~type_decl();
@ -736,7 +742,7 @@ public:
virtual bool
operator==(const decl_base&) const;
virtual void
virtual bool
traverse(ir_node_visitor&);
virtual ~namespace_decl();
@ -794,7 +800,7 @@ public:
virtual void
get_qualified_name(string& qualified_name) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~qualified_type_def();
@ -837,7 +843,7 @@ public:
virtual void
get_qualified_name(string&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~pointer_type_def();
@ -879,7 +885,7 @@ public:
virtual void
get_qualified_name(string& qualified_name) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~reference_type_def();
@ -990,7 +996,7 @@ public:
virtual bool
operator==(const type_base&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~enum_type_decl();
@ -1028,7 +1034,7 @@ public:
const shared_ptr<type_base>&
get_underlying_type() const;
virtual void
virtual bool
traverse(ir_node_visitor&);
virtual ~typedef_decl();
@ -1150,7 +1156,7 @@ public:
virtual string
get_pretty_representation() const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~var_decl();
@ -1420,7 +1426,7 @@ public:
&& get_parameters().back()->get_variadic_marker());
}
virtual void
virtual bool
traverse(ir_node_visitor&);
virtual ~function_decl();
@ -1825,7 +1831,7 @@ public:
get_binding() const
{return binding_;}
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~function_tdecl();
@ -1871,7 +1877,7 @@ public:
get_pattern() const
{return pattern_;}
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~class_tdecl();
@ -2061,7 +2067,7 @@ public:
bool
operator==(const class_decl&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
virtual ~class_decl();
@ -2380,7 +2386,7 @@ public:
virtual bool
operator==(const member_base& o) const;
virtual void
virtual bool
traverse(ir_node_visitor&);
};// end class class_decl::member_function_template
@ -2423,7 +2429,7 @@ public:
virtual bool
operator==(const member_class_template&) const;
virtual void
virtual bool
traverse(ir_node_visitor& v);
};// end class class_decl::member_class_template
@ -2584,21 +2590,21 @@ struct class_tdecl::shared_ptr_hash
/// where the traversal is supposed to start from.
struct ir_node_visitor : public node_visitor_base
{
virtual void visit(scope_decl*);
virtual void visit(type_decl*);
virtual void visit(namespace_decl*);
virtual void visit(qualified_type_def*);
virtual void visit(pointer_type_def*);
virtual void visit(reference_type_def*);
virtual void visit(enum_type_decl*);
virtual void visit(typedef_decl*);
virtual void visit(var_decl*);
virtual void visit(function_decl*);
virtual void visit(function_tdecl*);
virtual void visit(class_tdecl*);
virtual void visit(class_decl*);
virtual void visit(class_decl::member_function_template*);
virtual void visit(class_decl::member_class_template*);
virtual bool visit(scope_decl*);
virtual bool visit(type_decl*);
virtual bool visit(namespace_decl*);
virtual bool visit(qualified_type_def*);
virtual bool visit(pointer_type_def*);
virtual bool visit(reference_type_def*);
virtual bool visit(enum_type_decl*);
virtual bool visit(typedef_decl*);
virtual bool visit(var_decl*);
virtual bool visit(function_decl*);
virtual bool visit(function_tdecl*);
virtual bool visit(class_tdecl*);
virtual bool visit(class_decl*);
virtual bool visit(class_decl::member_function_template*);
virtual bool visit(class_decl::member_class_template*);
};
// Debugging facility

View File

@ -53,7 +53,10 @@ struct traversable_base
/// argument.
///
/// @param v the visitor used during the traverse.
virtual void traverse(node_visitor_base& v);
///
/// @return true if traversed until the end of the type tree, false
/// otherwise.
virtual bool traverse(node_visitor_base& v);
};
}//end namespace abigail
#endif //__ABG_TRAVERSE_H__

View File

@ -425,9 +425,18 @@ public:
/// meaning work in progress).
///
/// @param fn the function being visited.
void
///
/// @return true if the traversal of the tree should continue, false
/// otherwise.
///
/// @return true if the traversal of the tree should continue, false
/// otherwise.
bool
visit(function_decl* fn)
{add_fn_to_wip_fns(fn);}
{
add_fn_to_wip_fns(fn);
return true;
}
/// This function is called while visiting a @ref var_decl IR node
/// of a translation unit.
@ -436,12 +445,16 @@ public:
/// meaning work in progress).
///
/// @param var the variable being visited.
void
///
/// @return true if the traversal of the tree should continue, false
/// otherwise.
bool
visit(var_decl* var)
{
if (!is_data_member(var)
|| get_member_is_static(var))
add_var_to_wip_vars(var);
return true;
}
};// end struct symtab_build_visitor_type

View File

@ -265,9 +265,12 @@ translation_unit::operator==(const translation_unit& other)const
///
/// @param v the visitor used on the member nodes of the translation
/// unit during the traversal.
void
///
/// @return true if the entire type IR tree got traversed, false
/// otherwise.
bool
translation_unit::traverse(ir_node_visitor& v)
{get_global_scope()->traverse(v);}
{return get_global_scope()->traverse(v);}
translation_unit::~translation_unit()
{}
@ -473,10 +476,14 @@ decl_base::~decl_base()
///
/// @param v the visitor used on the member nodes of the translation
/// unit during the traversal.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
decl_base::traverse(ir_node_visitor&)
{
// Do nothing in the base class.
return true;
}
/// Setter of the scope of the current decl.
@ -1172,10 +1179,14 @@ scope_decl::find_iterator_for_member(const decl_base_sptr decl,
///
/// @param v the visitor used on the current instance of scope_decl
/// and on its member nodes.
void
///
/// @return true if the traversal of the tree should continue, false
/// otherwise.
bool
scope_decl::traverse(ir_node_visitor &v)
{
v.visit(this);
if (!v.visit(this))
return false;
scope_decl::declarations::const_iterator i;
for (i = get_member_decls().begin();
@ -1185,8 +1196,10 @@ scope_decl::traverse(ir_node_visitor &v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
if (t)
t->traverse (v);
if (!t->traverse (v))
return false;
}
return true;
}
scope_decl::~scope_decl()
@ -2035,12 +2048,15 @@ type_decl::get_pretty_representation() const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
type_decl::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
type_decl::~type_decl()
{ }
{}
//</type_decl definitions>
// <scope_type_decl definitions>
@ -2125,10 +2141,14 @@ namespace_decl::operator==(const decl_base& o) const
///
/// @param v the visitor used on the current instance and on its
/// member nodes.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
namespace_decl::traverse(ir_node_visitor& v)
{
v.visit(this);
if (!v.visit(this))
return false;
scope_decl::declarations::const_iterator i;
for (i = get_member_decls().begin();
@ -2138,8 +2158,10 @@ namespace_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
if (t)
t->traverse (v);
if (!t->traverse (v))
return false;
}
return true;
}
namespace_decl::~namespace_decl()
@ -2252,9 +2274,12 @@ qualified_type_def::get_qualified_name(string& qualified_name) const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
qualified_type_def::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
qualified_type_def::~qualified_type_def()
{
@ -2417,9 +2442,12 @@ pointer_type_def::get_qualified_name(string& qn) const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
pointer_type_def::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
pointer_type_def::~pointer_type_def()
{}
@ -2500,9 +2528,12 @@ reference_type_def::get_qualified_name(string& qn) const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
reference_type_def::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
reference_type_def::~reference_type_def()
{}
@ -2531,9 +2562,12 @@ enum_type_decl::get_pretty_representation() const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
enum_type_decl::traverse(ir_node_visitor &v)
{v.visit(this);}
{return v.visit(this);}
/// Destructor for the enum type declaration.
enum_type_decl::~enum_type_decl()
@ -2650,9 +2684,12 @@ typedef_decl::get_underlying_type() const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
typedef_decl::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
typedef_decl::~typedef_decl()
{}
@ -2722,9 +2759,12 @@ var_decl::get_pretty_representation() const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
var_decl::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
var_decl::~var_decl()
{}
@ -3223,9 +3263,12 @@ function_decl::operator==(const decl_base& other) const
/// function.
///
/// @param v the visitor used on the current instance.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
function_decl::traverse(ir_node_visitor& v)
{v.visit(this);}
{return v.visit(this);}
function_decl::~function_decl()
{}
@ -3759,7 +3802,6 @@ class_decl::method_decl::set_scope(scope_decl* scope)
context_->set_scope(scope);
}
/// Return the number of virtual functions of this class_decl.
///
/// @return the number of virtual functions of this class_decl
@ -4102,10 +4144,14 @@ operator==(class_decl_sptr l, class_decl_sptr r)
///
/// @param v the visitor used on the current instance and on its
/// members.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_decl::traverse(ir_node_visitor& v)
{
v.visit(this);
if (!v.visit(this))
return false;
for (member_types::const_iterator i = get_member_types().begin();
i != get_member_types().end();
@ -4114,7 +4160,8 @@ class_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
assert(t);
t->traverse(v);
if (!t->traverse(v))
return false;
}
for (member_function_templates::const_iterator i =
@ -4125,7 +4172,8 @@ class_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
assert(t);
t->traverse(v);
if (!t->traverse(v))
return false;
}
for (member_class_templates::const_iterator i =
@ -4136,7 +4184,8 @@ class_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
assert(t);
t->traverse(v);
if (!t->traverse(v))
return false;
}
for (data_members::const_iterator i = get_data_members().begin();
@ -4146,7 +4195,8 @@ class_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
assert(t);
t->traverse(v);
if (!t->traverse(v))
return false;
}
for (member_functions::const_iterator i= get_member_functions().begin();
@ -4156,8 +4206,11 @@ class_decl::traverse(ir_node_visitor& v)
ir_traversable_base_sptr t =
dynamic_pointer_cast<ir_traversable_base>(*i);
assert(t);
t->traverse(v);
if (!t->traverse(v))
return false;
}
return true;
}
class_decl::~class_decl()
@ -4222,11 +4275,15 @@ operator==(class_decl::member_function_template_sptr l,
///
/// @param v the visitor used on the current instance and on its
/// underlying function template.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_decl::member_function_template::traverse(ir_node_visitor& v)
{
v.visit(this);
as_function_tdecl()->traverse(v);
if (!v.visit(this))
return false;
return as_function_tdecl()->traverse(v);
}
bool
@ -4271,11 +4328,16 @@ operator==(class_decl::member_class_template_sptr l,
///
/// @param v the visitor used on the current instance and on the class
/// pattern of the template.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_decl::member_class_template::traverse(ir_node_visitor& v)
{
v.visit(this);
as_class_tdecl()->get_pattern()->traverse(v);
if (!v.visit(this))
return false;
return as_class_tdecl()->get_pattern()->traverse(v);
}
/// Streaming operator for class_decl::access_specifier.
@ -4515,11 +4577,16 @@ function_tdecl::operator==(const template_decl& other) const
///
/// @param v the visitor used on the current instance and on the
/// function pattern of the template.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
function_tdecl::traverse(ir_node_visitor&v)
{
v.visit(this);
get_pattern()->traverse(v);
if (!v.visit(this))
return false;
return get_pattern()->traverse(v);
}
function_tdecl::~function_tdecl()
@ -4593,82 +4660,89 @@ class_tdecl::operator==(const class_tdecl& o) const
///
/// @param v the visitor used on the current instance and on the class
/// pattern of the template.
void
///
/// @return true if the entire IR node tree got traversed, false
/// otherwise.
bool
class_tdecl::traverse(ir_node_visitor&v)
{
v.visit(this);
if (!v.visit(this))
return false;
shared_ptr<class_decl> pattern = get_pattern();
if (pattern)
pattern->traverse(v);
if (!pattern->traverse(v))
return false;
return true;
}
class_tdecl::~class_tdecl()
{}
void
bool
ir_traversable_base::traverse(ir_node_visitor&)
{}
{return true;}
void
bool
ir_node_visitor::visit(scope_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(type_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(namespace_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(qualified_type_def*)
{}
{return true;}
void
bool
ir_node_visitor::visit(pointer_type_def*)
{}
{return true;}
void
bool
ir_node_visitor::visit(reference_type_def*)
{}
{return true;}
void
bool
ir_node_visitor::visit(enum_type_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(typedef_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(var_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(function_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(function_tdecl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(class_tdecl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(class_decl*)
{}
{return true;}
void
bool
ir_node_visitor::visit(class_decl::member_function_template*)
{}
{return true;}
void
bool
ir_node_visitor::visit(class_decl::member_class_template*)
{}
{return true;}
// <debugging facilities>

View File

@ -25,9 +25,8 @@
namespace abigail
{
void
bool
traversable_base::traverse(node_visitor_base&)
{
}
{return true;}
}// end namespace abigail

View File

@ -33,13 +33,19 @@ using std::cout;
struct name_printing_visitor : public abigail::ir_node_visitor
{
void
bool
visit(abigail::class_decl* klass)
{cout << "class name: " << klass->get_name() << "\n";}
{
cout << "class name: " << klass->get_name() << "\n";
return true;
}
void
bool
visit(abigail::namespace_decl* ns)
{cout << "namespace name: " << ns->get_name() << "\n";}
{
cout << "namespace name: " << ns->get_name() << "\n";
return true;
}
};
int