mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-20 08:20:46 +00:00
Support reading namespaces
* include/abg-fwd.h (get_global_scope): Return a const global_scope. Add a new overload that takes a naked pointer as parm. (insert_decl_into_scope, get_top_most_scope_under): Declare new entry points. * include/abg-ir.h (class decl_base, class scope_decl): Add insert_decl_into_scope as a friend of these classes. (scope_decl::{insert_decl_into_scope, find_iterator_for_member}): Declare new member. (scope_decl::get_member_decls): New non-const overload. * src/abg-dwarf-reader.cc (build_translation_unit): Remove the "recurse" parameter. Adjust the call to build_ir_node_from_die to read just public decls that are at namespace scope. Anything else should be dropped unless it's needed to emitting the public namespace-level decls. (build_namespace_decl_and_add_to_ir) (canonicalize_and_insert_type_into_ir): Define new static functions. (build_corpus): Adjust ad build_translation_unit doesn't have the "recurse" parameter anymore. (canonicalize_and_add_type_to_ir): Make this static. Fix comments. (build_ir_node_from_die): Take a new "only_public_decl" parameter. For DW_TAG_base_type case, use the new canonicalize_and_insert_type_into_ir to insert the type at the right place in the global scope making sure it is seen before the current scope. For pointer, references and qualified types, use canonicalize_and_insert_type_into_ir to add the type at the same scope as its underlying type. Handle DW_TAG_{namespace,module} using the new build_namespace_decl_and_add_to_ir function. Add some vertical spaces and some assertions. * src/abg-ir.cc (scope_decl::add_member_decl): Use scope_decl_sptr typedef. (scope_decl::{insert_member_decl,find_iterator_for_member}): Define new methods. (insert_decl_into_scope, get_top_most_scope_under): Define new functions. (get_global_scope): Constify the return type. (get_translation_unit): Adjust as get_global_scope now returns a const. * src/abg-reader.cc (get_translation_unit): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
f918fdb0f9
commit
643b02fd6a
@ -60,6 +60,7 @@ namespace abigail
|
||||
// Inject some types.
|
||||
using std::tr1::shared_ptr;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
// Pull in relational operators.
|
||||
using namespace std::rel_ops;
|
||||
@ -112,7 +113,7 @@ add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
|
||||
void
|
||||
add_decl_to_scope (shared_ptr<decl_base>, shared_ptr<scope_decl>);
|
||||
|
||||
global_scope*
|
||||
const global_scope*
|
||||
get_global_scope(const shared_ptr<decl_base>);
|
||||
|
||||
translation_unit*
|
||||
@ -160,11 +161,18 @@ add_decl_to_scope(shared_ptr<decl_base>, scope_decl*);
|
||||
void
|
||||
add_decl_to_scope(shared_ptr<decl_base>, shared_ptr<scope_decl>);
|
||||
|
||||
global_scope*
|
||||
get_global_scope(decl_base* decl);
|
||||
void
|
||||
insert_decl_into_scope(shared_ptr<decl_base>,
|
||||
vector<shared_ptr<decl_base> >::iterator,
|
||||
scope_decl*);
|
||||
|
||||
global_scope*
|
||||
get_global_scope(const shared_ptr<decl_base>);
|
||||
void
|
||||
insert_decl_into_scope(shared_ptr<decl_base>,
|
||||
vector<shared_ptr<decl_base> >::iterator,
|
||||
shared_ptr<scope_decl>);
|
||||
|
||||
const global_scope*
|
||||
get_global_scope(const decl_base* decl);
|
||||
|
||||
translation_unit*
|
||||
get_translation_unit(decl_base* decl);
|
||||
@ -178,6 +186,18 @@ get_type_name(const shared_ptr<type_base>);
|
||||
shared_ptr<decl_base>
|
||||
get_type_declaration(const shared_ptr<type_base>);
|
||||
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const decl_base*,
|
||||
const scope_decl*);
|
||||
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const shared_ptr<decl_base>,
|
||||
const scope_decl*);
|
||||
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const shared_ptr<decl_base>,
|
||||
const shared_ptr<scope_decl>);
|
||||
|
||||
void
|
||||
dump(const shared_ptr<decl_base>, std::ostream&);
|
||||
|
||||
|
@ -265,6 +265,12 @@ public:
|
||||
friend void
|
||||
add_decl_to_scope(shared_ptr<decl_base> dcl, scope_decl* scpe);
|
||||
|
||||
friend void
|
||||
insert_decl_into_scope(shared_ptr<decl_base>,
|
||||
vector<shared_ptr<decl_base> >::iterator,
|
||||
scope_decl*);
|
||||
|
||||
|
||||
friend class class_decl;
|
||||
};// end class decl_base
|
||||
|
||||
@ -300,6 +306,10 @@ protected:
|
||||
virtual void
|
||||
add_member_decl(const decl_base_sptr member);
|
||||
|
||||
virtual void
|
||||
insert_member_decl(const decl_base_sptr member,
|
||||
declarations::iterator before);
|
||||
|
||||
public:
|
||||
scope_decl(const std::string& name, location locus,
|
||||
visibility vis = VISIBILITY_DEFAULT)
|
||||
@ -316,14 +326,24 @@ public:
|
||||
get_member_decls() const
|
||||
{return members_;}
|
||||
|
||||
const scopes&
|
||||
get_member_scopes() const
|
||||
declarations&
|
||||
get_member_decls()
|
||||
{return members_;}
|
||||
|
||||
scopes&
|
||||
get_member_scopes()
|
||||
{return member_scopes_;}
|
||||
|
||||
bool
|
||||
is_empty() const
|
||||
{return get_member_decls().empty();}
|
||||
|
||||
bool
|
||||
find_iterator_for_member(const decl_base*, declarations::iterator&);
|
||||
|
||||
bool
|
||||
find_iterator_for_member(const decl_base_sptr, declarations::iterator&);
|
||||
|
||||
void
|
||||
traverse(ir_node_visitor&);
|
||||
|
||||
@ -331,6 +351,11 @@ public:
|
||||
|
||||
friend void
|
||||
add_decl_to_scope(shared_ptr<decl_base> dcl, scope_decl* scpe);
|
||||
|
||||
friend void
|
||||
insert_decl_into_scope(decl_base_sptr decl,
|
||||
scope_decl::declarations::iterator before,
|
||||
scope_decl* scope);
|
||||
};//end class scope_decl
|
||||
|
||||
/// Convenience typedef for shared pointer on @ref global_scope.
|
||||
|
@ -206,7 +206,8 @@ public:
|
||||
|
||||
static decl_base_sptr
|
||||
build_ir_node_from_die(read_context& ctxt,
|
||||
Dwarf_Die* die);
|
||||
Dwarf_Die* die,
|
||||
bool only_public_decl = false);
|
||||
|
||||
/// Constructor for a default Dwfl handle that knows how to load debug
|
||||
/// info from a library or executable elf file.
|
||||
@ -472,7 +473,9 @@ is_public_decl(Dwarf_Die* die)
|
||||
}
|
||||
|
||||
/// Given a DW_TAG_compile_unit, build and return the corresponding
|
||||
/// abigail::translation_unit ir node.
|
||||
/// abigail::translation_unit ir node. Note that this function
|
||||
/// recursively reads the children dies of the current DIE and
|
||||
/// populates the resulting translation unit.
|
||||
///
|
||||
/// @param ctxt the read_context to use.
|
||||
///
|
||||
@ -489,8 +492,7 @@ is_public_decl(Dwarf_Die* die)
|
||||
static translation_unit_sptr
|
||||
build_translation_unit(read_context& ctxt,
|
||||
Dwarf_Die* die,
|
||||
char address_size,
|
||||
bool recurse = false)
|
||||
char address_size)
|
||||
{
|
||||
translation_unit_sptr result;
|
||||
|
||||
@ -505,17 +507,64 @@ build_translation_unit(read_context& ctxt,
|
||||
ctxt.current_translation_unit(result);
|
||||
|
||||
Dwarf_Die child;
|
||||
if (!recurse
|
||||
|| (dwarf_child(die, &child) != 0))
|
||||
if (dwarf_child(die, &child) != 0)
|
||||
return result;
|
||||
|
||||
do
|
||||
build_ir_node_from_die(ctxt, &child);
|
||||
build_ir_node_from_die(ctxt, &child, /*only_public_decl=*/true);
|
||||
while (dwarf_siblingof(&child, &child) == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Build a @ref namespace_decl out of a DW_TAG_namespace or
|
||||
/// DW_TAG_module (for fortran) DIE.
|
||||
///
|
||||
/// Note that this function connects the DW_TAG_namespace to the IR
|
||||
/// being currently created, reads the children of the DIE and
|
||||
/// connects them to the IR as well.
|
||||
///
|
||||
/// @param ctxt the read context to use.
|
||||
///
|
||||
/// @param die the DIE to read from. Must be either DW_TAG_namespace
|
||||
/// or DW_TAG_module.
|
||||
///
|
||||
/// @return the resulting @ref nampespace_decl or NULL if it couldn't
|
||||
/// be created.
|
||||
static namespace_decl_sptr
|
||||
build_namespace_decl_and_add_to_ir(read_context& ctxt,
|
||||
Dwarf_Die* die)
|
||||
{
|
||||
namespace_decl_sptr result;
|
||||
|
||||
if (!die)
|
||||
return result;
|
||||
|
||||
unsigned tag = dwarf_tag(die);
|
||||
if (tag != DW_TAG_namespace && tag != DW_TAG_module)
|
||||
return result;
|
||||
|
||||
string name, mangled_name;
|
||||
location loc;
|
||||
die_loc_and_name(ctxt, die, loc, name, mangled_name);
|
||||
|
||||
result.reset(new namespace_decl(name, loc));
|
||||
add_decl_to_scope(result, ctxt.current_scope());
|
||||
|
||||
Dwarf_Die child;
|
||||
|
||||
if (dwarf_child(die, &child) != 0)
|
||||
return result;
|
||||
|
||||
ctxt.scope_stack().push(result);
|
||||
do
|
||||
build_ir_node_from_die(ctxt, &child, /*only_public_decl=*/true);
|
||||
while (dwarf_siblingof(&child, &child) == 0);
|
||||
ctxt.scope_stack().pop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Build a @ref type_decl out of a DW_TAG_base_type DIE.
|
||||
///
|
||||
/// @param ctxt the read context to use.
|
||||
@ -885,23 +934,24 @@ build_corpus(read_context& ctxt)
|
||||
// Build a translation_unit IR node from cu; note that cu must
|
||||
// be a DW_TAG_compile_unit die.
|
||||
translation_unit_sptr ir_node =
|
||||
build_translation_unit(ctxt, &cu, address_size, /*recurse=*/true);
|
||||
build_translation_unit(ctxt, &cu, address_size);
|
||||
assert(ir_node);
|
||||
}
|
||||
return ctxt.current_corpus();
|
||||
}
|
||||
|
||||
/// Canonicalize a type and add it to the current IR being built, if
|
||||
/// necessary.
|
||||
/// necessary. The canonicalized type is appended to the children IR
|
||||
/// nodes of a given scope.
|
||||
///
|
||||
/// @param type_declaration the declaration of the type to
|
||||
/// canonicalize.
|
||||
///
|
||||
/// @param type_scope the scope into which the canonicalized type
|
||||
/// needs to be added to.
|
||||
/// @param type_scope the scope into which the canonicalized type is
|
||||
/// to be added.
|
||||
///
|
||||
/// @return the resulting canonicalized type.
|
||||
decl_base_sptr
|
||||
static decl_base_sptr
|
||||
canonicalize_and_add_type_to_ir(decl_base_sptr type_declaration,
|
||||
scope_decl* type_scope)
|
||||
{
|
||||
@ -938,7 +988,7 @@ canonicalize_and_add_type_to_ir(decl_base_sptr type_declaration,
|
||||
/// canonicalize.
|
||||
///
|
||||
/// @param type_scope the scope into which the canonicalized type
|
||||
/// needs to be added to.
|
||||
/// needs to be added.
|
||||
///
|
||||
/// @return the resulting canonicalized type.
|
||||
decl_base_sptr
|
||||
@ -946,17 +996,124 @@ canonicalize_and_add_type_to_ir(decl_base_sptr type_declaration,
|
||||
scope_decl_sptr type_scope)
|
||||
{return canonicalize_and_add_type_to_ir(type_declaration, type_scope.get());}
|
||||
|
||||
/// Canonicalize a given type and insert it into the children of a
|
||||
/// given scope right before a given child.
|
||||
///
|
||||
/// @param type_declaration the declaration of the type to canonicalize.
|
||||
///
|
||||
/// @param before an iterator pointing to an IR node that is a child
|
||||
/// of the scope under wich the canonicalized type is to be inserted.
|
||||
/// The canonicalized type is to be inserted right before that
|
||||
/// iterator.
|
||||
static decl_base_sptr
|
||||
canonicalize_and_insert_type_into_ir(decl_base_sptr type_declaration,
|
||||
scope_decl::declarations::iterator before,
|
||||
scope_decl* type_scope)
|
||||
{
|
||||
if (!type_declaration)
|
||||
return type_declaration;
|
||||
|
||||
translation_unit* tu = get_translation_unit(type_scope);
|
||||
assert(tu);
|
||||
|
||||
/// TODO: maybe change the interfance of
|
||||
/// translation_unit::canonicalize_type to include the final
|
||||
/// qualified name of the type (i.e, one that includes the qualified
|
||||
/// name of type_scope), to handle two user defined types that might
|
||||
/// be same, but at different scopes. In that case, the two types
|
||||
/// should be considered different by
|
||||
/// translation_unit::canonicalize_type.
|
||||
decl_base_sptr result = tu->canonicalize_type(type_declaration);
|
||||
assert(result);
|
||||
|
||||
if (result->get_scope())
|
||||
// This type is the same as a type that was already added to the
|
||||
// IR tree. Do not add a new one. Just re-use the previous one.
|
||||
;
|
||||
else
|
||||
insert_decl_into_scope(result, before, type_scope);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Canonicalize a type and insert it into the current IR. The
|
||||
/// canonicalized type is to be inserted before the current scope C
|
||||
/// and under a given scope S. If C and S are equal the the
|
||||
/// canonicalized type is just appended to the current scope.
|
||||
///
|
||||
/// @param ctxt the read context to consider.
|
||||
///
|
||||
/// @param type_decl the declaration of the type to canonicalize.
|
||||
///
|
||||
/// @param scope the scope under which the canonicalized type is to be
|
||||
/// added. This must be a scope that is higher or equal to the
|
||||
/// current scope.
|
||||
///
|
||||
/// @return the declaration of the canonicalized type.
|
||||
static decl_base_sptr
|
||||
canonicalize_and_insert_type_into_ir_under_scope(read_context& ctxt,
|
||||
decl_base_sptr type_decl,
|
||||
scope_decl* scope)
|
||||
{
|
||||
decl_base_sptr result;
|
||||
|
||||
const scope_decl* ns_under_scope =
|
||||
get_top_most_scope_under(ctxt.current_scope(), scope);
|
||||
|
||||
if (ns_under_scope == scope)
|
||||
result =
|
||||
canonicalize_and_add_type_to_ir(type_decl, scope);
|
||||
else
|
||||
{
|
||||
scope_decl::declarations::iterator it;
|
||||
assert(scope->find_iterator_for_member(ns_under_scope,
|
||||
it));
|
||||
result =
|
||||
canonicalize_and_insert_type_into_ir(type_decl, it, scope);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Canonicalize a type and insert it into the current IR. The
|
||||
/// canonicalized type is to be inserted before the current scope C
|
||||
/// and under a given scope S. If C and S are equal the the
|
||||
/// canonicalized type is just appended to the current scope.
|
||||
///
|
||||
/// @param ctxt the read context to consider.
|
||||
///
|
||||
/// @param type_decl the declaration of the type to canonicalize.
|
||||
///
|
||||
/// @param scope the scope under which the canonicalized type is to be
|
||||
/// added. This must be a scope that is higher or equal to the
|
||||
/// current scope.
|
||||
///
|
||||
/// @return the declaration of the canonicalized type.
|
||||
static decl_base_sptr
|
||||
canonicalize_and_insert_type_into_ir_under_scope(read_context& ctxt,
|
||||
decl_base_sptr type_decl,
|
||||
scope_decl_sptr scope)
|
||||
{return canonicalize_and_insert_type_into_ir_under_scope(ctxt, type_decl,
|
||||
scope.get());}
|
||||
|
||||
/// Build an IR node from a given DIE and add the node to the current
|
||||
/// IR being build and held in the read_context.
|
||||
/// IR being build and held in the read_context. Doing that is called
|
||||
/// "emitting an IR node for the DIE".
|
||||
///
|
||||
/// @param ctxt the read context.
|
||||
///
|
||||
/// @parm die the DIE to consider.
|
||||
///
|
||||
/// @param only_public_decl if yes, only namespace-level declarations
|
||||
/// that are public are emitted. The types needed to emit these
|
||||
/// public declaration are emitted too, and added to the IR at a point
|
||||
/// that is before the point of emitting the decl.
|
||||
///
|
||||
/// @return the resulting IR node.
|
||||
static decl_base_sptr
|
||||
build_ir_node_from_die(read_context& ctxt,
|
||||
Dwarf_Die* die)
|
||||
Dwarf_Die* die,
|
||||
bool only_public_decl)
|
||||
{
|
||||
decl_base_sptr result;
|
||||
|
||||
@ -968,6 +1125,16 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
return it->second;
|
||||
|
||||
int tag = dwarf_tag(die);
|
||||
|
||||
if (only_public_decl == true)
|
||||
{
|
||||
if (!(tag == DW_TAG_namespace
|
||||
|| tag == DW_TAG_module
|
||||
|| tag == DW_TAG_subprogram
|
||||
|| tag == DW_TAG_variable))
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
// Type DIEs we intent to support someday, maybe.
|
||||
@ -975,9 +1142,10 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
if((result = build_type_decl(ctxt, die)))
|
||||
{
|
||||
translation_unit_sptr tu = ctxt.current_translation_unit();
|
||||
result =
|
||||
canonicalize_and_add_type_to_ir(result,
|
||||
tu->get_global_scope());
|
||||
global_scope_sptr gscope = tu->get_global_scope();
|
||||
result = canonicalize_and_insert_type_into_ir_under_scope(ctxt,
|
||||
result,
|
||||
gscope);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -991,10 +1159,11 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
case DW_TAG_pointer_type:
|
||||
{
|
||||
pointer_type_def_sptr p = build_pointer_type_def(ctxt, die);
|
||||
decl_base_sptr underlying_type =
|
||||
decl_base_sptr utype =
|
||||
get_type_declaration(p->get_pointed_to_type());
|
||||
result =
|
||||
canonicalize_and_add_type_to_ir(p, underlying_type->get_scope());
|
||||
canonicalize_and_insert_type_into_ir_under_scope(ctxt, p,
|
||||
utype->get_scope());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1002,10 +1171,11 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
case DW_TAG_rvalue_reference_type:
|
||||
{
|
||||
reference_type_def_sptr r = build_reference_type(ctxt, die);
|
||||
decl_base_sptr underlying_type =
|
||||
decl_base_sptr utype =
|
||||
get_type_declaration(r->get_pointed_to_type());
|
||||
result =
|
||||
canonicalize_and_add_type_to_ir(r, underlying_type->get_scope());
|
||||
canonicalize_and_insert_type_into_ir_under_scope(ctxt, r,
|
||||
utype->get_scope());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1015,10 +1185,11 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
qualified_type_def_sptr q = build_qualified_type(ctxt, die);
|
||||
if (q)
|
||||
{
|
||||
decl_base_sptr underlying_type =
|
||||
decl_base_sptr t =
|
||||
get_type_declaration(q->get_underlying_type());
|
||||
result =
|
||||
canonicalize_and_add_type_to_ir(q, underlying_type->get_scope());
|
||||
canonicalize_and_insert_type_into_ir_under_scope(ctxt, q,
|
||||
t->get_scope());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1069,17 +1240,26 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
break;
|
||||
|
||||
case DW_TAG_namespace:
|
||||
case DW_TAG_module:
|
||||
result = build_namespace_decl_and_add_to_ir(ctxt, die);
|
||||
break;
|
||||
|
||||
case DW_TAG_variable:
|
||||
if ((result = build_var_decl(ctxt, die)))
|
||||
add_decl_to_scope(result, ctxt.current_scope());
|
||||
break;
|
||||
|
||||
case DW_TAG_subprogram:
|
||||
if ((result = build_function_decl(ctxt, die)))
|
||||
add_decl_to_scope(result, ctxt.current_scope());
|
||||
break;
|
||||
|
||||
case DW_TAG_formal_parameter:
|
||||
// We should not read this case as it should have been dealt
|
||||
// with by build_function_decl above.
|
||||
abort();
|
||||
break;
|
||||
|
||||
case DW_TAG_constant:
|
||||
break;
|
||||
case DW_TAG_enumerator:
|
||||
@ -1098,7 +1278,6 @@ build_ir_node_from_die(read_context& ctxt,
|
||||
case DW_TAG_common_inclusion:
|
||||
case DW_TAG_inheritance:
|
||||
case DW_TAG_inlined_subroutine:
|
||||
case DW_TAG_module:
|
||||
case DW_TAG_with_stmt:
|
||||
case DW_TAG_access_declaration:
|
||||
case DW_TAG_catch_block:
|
||||
|
169
src/abg-ir.cc
169
src/abg-ir.cc
@ -513,7 +513,25 @@ scope_decl::add_member_decl(const shared_ptr<decl_base> member)
|
||||
{
|
||||
members_.push_back(member);
|
||||
|
||||
if (shared_ptr<scope_decl> m = dynamic_pointer_cast<scope_decl>(member))
|
||||
if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
|
||||
member_scopes_.push_back(m);
|
||||
}
|
||||
|
||||
/// Insert a member decl to this scope, right before an element
|
||||
/// pointed to by a given iterator. Note that user code should not
|
||||
/// use this, but rather use insert_decl_into_scope.
|
||||
///
|
||||
/// @param member the new member decl to add to this scope.
|
||||
///
|
||||
/// @param before an interator pointing to the element before which
|
||||
/// the new member should be inserted.
|
||||
void
|
||||
scope_decl::insert_member_decl(const decl_base_sptr member,
|
||||
declarations::iterator before)
|
||||
{
|
||||
members_.insert(before, member);
|
||||
|
||||
if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
|
||||
member_scopes_.push_back(m);
|
||||
}
|
||||
|
||||
@ -549,6 +567,46 @@ scope_decl::operator==(const decl_base& o) const
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Find a member of the current scope and return an iterator on it.
|
||||
///
|
||||
/// @param decl the scope member to find.
|
||||
///
|
||||
/// @param i the iterator to set to the member @ref decl. This is set
|
||||
/// iff the function returns true.
|
||||
///
|
||||
/// @return true if the member decl was found, false otherwise.
|
||||
bool
|
||||
scope_decl::find_iterator_for_member(const decl_base* decl,
|
||||
declarations::iterator& i)
|
||||
{
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
for (declarations::iterator it = get_member_decls().begin();
|
||||
it != get_member_decls().end();
|
||||
++it)
|
||||
if (**it == *decl)
|
||||
{
|
||||
i = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Find a member of the current scope and return an iterator on it.
|
||||
///
|
||||
/// @param decl the scope member to find.
|
||||
///
|
||||
/// @param i the iterator to set to the member @ref decl. This is set
|
||||
/// iff the function returns true.
|
||||
///
|
||||
/// @return true if the member decl was found, false otherwise.
|
||||
bool
|
||||
scope_decl::find_iterator_for_member(const decl_base_sptr decl,
|
||||
declarations::iterator& i)
|
||||
{return find_iterator_for_member(decl.get(), i);}
|
||||
|
||||
/// This implements the traversable_base::traverse pure virtual
|
||||
/// function.
|
||||
///
|
||||
@ -600,16 +658,52 @@ void
|
||||
add_decl_to_scope(shared_ptr<decl_base> decl, shared_ptr<scope_decl> scope)
|
||||
{add_decl_to_scope(decl, scope.get());}
|
||||
|
||||
/// Return the global scope as seen by a given declaration.
|
||||
/// Inserts a declaration into a given scope, before a given IR child
|
||||
/// node of the scope.
|
||||
///
|
||||
/// @param decl the declaration to insert into the scope.
|
||||
///
|
||||
/// @param before an iterator pointing to the child IR node before
|
||||
/// which to insert the declaration.
|
||||
///
|
||||
/// @param scope the scope into which to insert the declaration.
|
||||
void
|
||||
insert_decl_into_scope(decl_base_sptr decl,
|
||||
scope_decl::declarations::iterator before,
|
||||
scope_decl* scope)
|
||||
{
|
||||
if (scope && decl && !decl->get_scope())
|
||||
{
|
||||
scope->insert_member_decl(decl, before);
|
||||
decl->set_scope(scope);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts a declaration into a given scope, before a given IR child
|
||||
/// node of the scope.
|
||||
///
|
||||
/// @param decl the declaration to insert into the scope.
|
||||
///
|
||||
/// @param before an iterator pointing to the child IR node before
|
||||
/// which to insert the declaration.
|
||||
///
|
||||
/// @param scope the scope into which to insert the declaration.
|
||||
void
|
||||
insert_decl_into_scope(decl_base_sptr decl,
|
||||
scope_decl::declarations::iterator before,
|
||||
scope_decl_sptr scope)
|
||||
{insert_decl_into_scope(decl, before, scope.get());}
|
||||
|
||||
/// return the global scope as seen by a given declaration.
|
||||
///
|
||||
/// @param decl the declaration to consider.
|
||||
///
|
||||
/// @return the global scope of the decl, or a null pointer if the
|
||||
/// decl is not yet added to a translation_unit.
|
||||
global_scope*
|
||||
get_global_scope(decl_base* decl)
|
||||
const global_scope*
|
||||
get_global_scope(const decl_base* decl)
|
||||
{
|
||||
if (global_scope* s = dynamic_cast<global_scope*>(decl))
|
||||
if (const global_scope* s = dynamic_cast<const global_scope*>(decl))
|
||||
return s;
|
||||
|
||||
scope_decl* scope = decl->get_scope();
|
||||
@ -625,19 +719,68 @@ get_global_scope(decl_base* decl)
|
||||
///
|
||||
/// @return the global scope of the decl, or a null pointer if the
|
||||
/// decl is not yet added to a translation_unit.
|
||||
global_scope*
|
||||
const global_scope*
|
||||
get_global_scope(const shared_ptr<decl_base> decl)
|
||||
{return get_global_scope(decl.get());}
|
||||
|
||||
/// Return the a scope S containing a given declaration and that is
|
||||
/// right under a given scope P.
|
||||
///
|
||||
/// @param decl the decl for which to find a scope.
|
||||
///
|
||||
/// @param scope the scope under which the resulting scope must be.
|
||||
///
|
||||
/// @return the resulting scope.
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const decl_base* decl,
|
||||
const scope_decl* scope)
|
||||
{
|
||||
if (shared_ptr<global_scope> s = dynamic_pointer_cast<global_scope>(decl))
|
||||
return s.get();
|
||||
if (!decl)
|
||||
return 0;
|
||||
|
||||
scope_decl* scope = decl->get_scope();
|
||||
while (scope && !dynamic_cast<global_scope*>(scope))
|
||||
scope = scope->get_scope();
|
||||
if (scope == 0)
|
||||
return get_global_scope(decl);
|
||||
|
||||
return scope ? dynamic_cast<global_scope*> (scope) : 0;
|
||||
const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
|
||||
if (!s)
|
||||
s = decl->get_scope();
|
||||
|
||||
while (!is_global_scope(s) && s->get_scope() != scope)
|
||||
s = s->get_scope();
|
||||
|
||||
if (is_global_scope(s))
|
||||
assert(is_global_scope(scope));
|
||||
assert(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Return the a scope S containing a given declaration and that is
|
||||
/// right under a given scope P.
|
||||
///
|
||||
/// @param decl the decl for which to find a scope.
|
||||
///
|
||||
/// @param scope the scope under which the resulting scope must be.
|
||||
///
|
||||
/// @return the resulting scope.
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const decl_base_sptr decl,
|
||||
const scope_decl* scope)
|
||||
{return get_top_most_scope_under(decl.get(), scope);}
|
||||
|
||||
/// Return the a scope S containing a given declaration and that is
|
||||
/// right under a given scope P.
|
||||
///
|
||||
/// @param decl the decl for which to find a scope.
|
||||
///
|
||||
/// @param scope the scope under which the resulting scope must be.
|
||||
///
|
||||
/// @return the resulting scope.
|
||||
const scope_decl*
|
||||
get_top_most_scope_under(const decl_base_sptr decl,
|
||||
const scope_decl_sptr scope)
|
||||
{return get_top_most_scope_under(decl, scope.get());}
|
||||
|
||||
/// Get the name of a given type and return a copy of it.
|
||||
///
|
||||
/// @return a copy of the type name if the type has a name, or the
|
||||
@ -667,7 +810,7 @@ get_type_declaration(const type_base_sptr t)
|
||||
translation_unit*
|
||||
get_translation_unit(decl_base* decl)
|
||||
{
|
||||
global_scope* global = get_global_scope(decl);
|
||||
const global_scope* global = get_global_scope(decl);
|
||||
|
||||
if (global)
|
||||
return global->get_translation_unit();
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
translation_unit*
|
||||
get_translation_unit()
|
||||
{
|
||||
global_scope* global = 0;
|
||||
const global_scope* global = 0;
|
||||
if (shared_ptr<decl_base> d = get_cur_decl ())
|
||||
global = get_global_scope(d);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user