static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *,
const char *namespace);
+static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace);
+
static char *add_partial_namespace (struct partial_die_info *pdi,
char *info_ptr,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
struct dwarf2_cu *cu,
const char *namespace);
+static char *add_partial_structure (struct partial_die_info *struct_pdi,
+ char *info_ptr,
+ struct dwarf2_cu *cu,
+ const char *namespace);
+
static char *add_partial_enumeration (struct partial_die_info *enum_pdi,
char *info_ptr,
struct dwarf2_cu *cu,
static int die_is_declaration (struct die_info *);
+static struct die_info *die_specification (struct die_info *die);
+
static void free_line_header (struct line_header *lh);
static struct line_header *(dwarf_decode_line_header
static void read_type_die (struct die_info *, struct dwarf2_cu *);
+static char *determine_prefix (struct die_info *die);
+
+static char *typename_concat (const char *prefix, const char *suffix);
+
+static char *class_name (struct die_info *die);
+
static void read_typedef (struct die_info *, struct dwarf2_cu *);
static void read_base_type (struct die_info *, struct dwarf2_cu *);
case DW_TAG_variable:
case DW_TAG_typedef:
case DW_TAG_union_type:
+ if (!pdi.is_declaration)
+ {
+ add_partial_symbol (&pdi, cu, namespace);
+ }
+ break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
if (!pdi.is_declaration)
{
- add_partial_symbol (&pdi, cu, namespace);
+ info_ptr = add_partial_structure (&pdi, info_ptr, cu,
+ namespace);
+ info_ptr_updated = 1;
}
break;
case DW_TAG_enumeration_type:
char *actual_name = pdi->name;
const struct partial_symbol *psym = NULL;
+ /* If we're not in the global namespace and if the namespace name
+ isn't encoded in a mangled actual_name, add it. */
+
+ if (pdi_needs_namespace (pdi->tag, namespace))
+ {
+ actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1);
+ strcpy (actual_name, namespace);
+ strcat (actual_name, "::");
+ strcat (actual_name, pdi->name);
+ }
+
switch (pdi->tag)
{
case DW_TAG_subprogram:
case DW_TAG_enumeration_type:
/* Skip aggregate types without children, these are external
references. */
+ /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+ static vs. global. */
if (pdi->has_children == 0)
return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
- &objfile->static_psymbols,
+ cu_language == language_cplus
+ ? &objfile->global_psymbols
+ : &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
if (cu_language == language_cplus)
/* For C++, these implicitly act as typedefs as well. */
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->static_psymbols,
+ &objfile->global_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
}
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_CONST,
- &objfile->static_psymbols,
+ cu_language == language_cplus
+ ? &objfile->static_psymbols
+ : &objfile->global_psymbols,
0, (CORE_ADDR) 0, cu_language, objfile);
break;
default:
objfile);
}
+/* Determine whether a die of type TAG living in the C++ namespace
+ NAMESPACE needs to have the name of the namespace prepended to the
+ name listed in the die. */
+
+static int
+pdi_needs_namespace (enum dwarf_tag tag, const char *namespace)
+{
+ if (namespace == NULL || namespace[0] == '\0')
+ return 0;
+
+ switch (tag)
+ {
+ case DW_TAG_typedef:
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_enumerator:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/* Read a partial die corresponding to a namespace; also, add a symbol
corresponding to that namespace to the symbol table. NAMESPACE is
the name of the enclosing namespace. */
strcat (full_name, "::");
strcat (full_name, new_name);
- /* FIXME: carlton/2003-06-27: Once we build qualified names for more
- symbols than just namespaces, we should replace this by a call to
- add_partial_symbol. */
+ /* FIXME: carlton/2003-10-07: We can't just replace this by a call
+ to add_partial_symbol, because we don't have a way to pass in the
+ full name to that function; that might be a flaw in
+ add_partial_symbol's interface. */
add_psymbol_to_list (full_name, strlen (full_name),
VAR_DOMAIN, LOC_TYPEDEF,
return info_ptr;
}
+/* Read a partial die corresponding to a class or structure. */
+
+static char *
+add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr,
+ struct dwarf2_cu *cu,
+ const char *namespace)
+{
+ bfd *abfd = cu->objfile->obfd;
+ char *actual_class_name = NULL;
+
+ if (cu_language == language_cplus
+ && namespace == NULL
+ && struct_pdi->name != NULL
+ && struct_pdi->has_children)
+ {
+ /* We don't have namespace debugging information, so see if we
+ can figure out if this structure lives in a namespace. Look
+ for a member function; its demangled name will contain
+ namespace info, if there is any. */
+
+ /* NOTE: carlton/2003-10-07: Getting the info this way changes
+ what template types look like, because the demangler
+ frequently doesn't give the same name as the debug info. We
+ could fix this by only using the demangled name to get the
+ prefix (but see comment in read_structure_scope). */
+
+ char *next_child = info_ptr;
+
+ while (1)
+ {
+ struct partial_die_info child_pdi;
+
+ next_child = read_partial_die (&child_pdi, abfd, next_child,
+ cu);
+ if (!child_pdi.tag)
+ break;
+ if (child_pdi.tag == DW_TAG_subprogram)
+ {
+ actual_class_name = class_name_from_physname (child_pdi.name);
+ if (actual_class_name != NULL)
+ struct_pdi->name = actual_class_name;
+ break;
+ }
+ else
+ {
+ next_child = locate_pdi_sibling (&child_pdi, next_child,
+ abfd, cu);
+ }
+ }
+ }
+
+ add_partial_symbol (struct_pdi, cu, namespace);
+ xfree(actual_class_name);
+
+ return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
+}
+
/* Read a partial die corresponding to an enumeration type. */
static char *
cu_header_offset = offset;
info_ptr = dwarf_info_buffer + offset;
+ /* We're in the global namespace. */
+ processing_current_prefix = "";
+
obstack_init (&dwarf2_tmp_obstack);
back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
case DW_TAG_common_inclusion:
break;
case DW_TAG_namespace:
- if (!processing_has_namespace_info)
- {
- processing_has_namespace_info = 1;
- processing_current_prefix = "";
- }
+ processing_has_namespace_info = 1;
read_namespace (die, cu);
break;
case DW_TAG_imported_declaration:
shouldn't in the C++ case, but conceivably could in the
Fortran case, so we'll have to replace this gdb_assert if
Fortran compilers start generating that info. */
- if (!processing_has_namespace_info)
- {
- processing_has_namespace_info = 1;
- processing_current_prefix = "";
- }
+ processing_has_namespace_info = 1;
gdb_assert (die->child == NULL);
break;
default:
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
+ const char *name = NULL;
+ const char *previous_prefix = processing_current_prefix;
+ struct cleanup *back_to = NULL;
+ /* This says whether or not we want to try to update the structure's
+ name to include enclosing namespace/class information, if
+ any. */
+ int need_to_update_name = 0;
type = alloc_type (objfile);
attr = dwarf_attr (die, DW_AT_name);
if (attr && DW_STRING (attr))
{
- TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
- strlen (DW_STRING (attr)),
- &objfile->type_obstack);
+ name = DW_STRING (attr);
+
+ if (cu_language == language_cplus)
+ {
+ struct die_info *spec_die = die_specification (die);
+
+ if (spec_die != NULL)
+ {
+ char *specification_prefix = determine_prefix (spec_die);
+ processing_current_prefix = specification_prefix;
+ back_to = make_cleanup (xfree, specification_prefix);
+ }
+ }
+
+ if (processing_has_namespace_info)
+ {
+ /* FIXME: carlton/2003-11-10: This variable exists only for
+ const-correctness reasons. When I tried to change
+ TYPE_TAG_NAME to be a const char *, I ran into a cascade
+ of changes which would have forced decode_line_1 to take
+ a const char **. */
+ char *new_prefix = obconcat (&objfile->type_obstack,
+ processing_current_prefix,
+ processing_current_prefix[0] == '\0'
+ ? "" : "::",
+ name);
+ TYPE_TAG_NAME (type) = new_prefix;
+ processing_current_prefix = new_prefix;
+ }
+ else
+ {
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+ &objfile->type_obstack);
+ need_to_update_name = (cu_language == language_cplus);
+ }
}
if (die->tag == DW_TAG_structure_type)
/* C++ member function. */
process_die (child_die, cu);
dwarf2_add_member_fn (&fi, child_die, type, cu);
+ if (need_to_update_name)
+ {
+ /* The demangled names of member functions contain
+ information about enclosing namespaces/classes,
+ if any. */
+
+ /* FIXME: carlton/2003-11-10: The excessive
+ demangling here is a bit wasteful, as is the
+ memory usage for names. */
+
+ /* NOTE: carlton/2003-11-10: As commented in
+ add_partial_structure, the demangler sometimes
+ prints the type info in a different form from the
+ debug info. We could solve this by using the
+ demangled name to get the prefix; if doing so,
+ however, we'd need to be careful when reading a
+ class that's nested inside a template class.
+ That would also cause problems when trying to
+ determine RTTI information, since we use the
+ demangler to determine the appropriate class
+ name. */
+ char *actual_class_name
+ = class_name_from_physname (dwarf2_linkage_name
+ (child_die));
+ if (actual_class_name != NULL
+ && strcmp (actual_class_name, name) != 0)
+ {
+ TYPE_TAG_NAME (type)
+ = obsavestring (actual_class_name,
+ strlen (actual_class_name),
+ &objfile->type_obstack);
+ }
+ xfree (actual_class_name);
+ need_to_update_name = 0;
+ }
}
else if (child_die->tag == DW_TAG_inheritance)
{
/* No children, must be stub. */
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
}
+
+ processing_current_prefix = previous_prefix;
+ if (back_to != NULL)
+ do_cleanups (back_to);
}
/* Given a pointer to a die which begins an enumeration, process all
attr = dwarf_attr (die, DW_AT_name);
if (attr && DW_STRING (attr))
{
- TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr),
- strlen (DW_STRING (attr)),
- &objfile->type_obstack);
+ const char *name = DW_STRING (attr);
+
+ if (processing_has_namespace_info)
+ {
+ TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+ processing_current_prefix,
+ processing_current_prefix[0] == '\0'
+ ? "" : "::",
+ name);
+ }
+ else
+ {
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
+ &objfile->type_obstack);
+ }
}
attr = dwarf_attr (die, DW_AT_byte_size);
{
struct objfile *objfile = cu->objfile;
const char *previous_prefix = processing_current_prefix;
- const char *name = NULL;
+ const char *name;
int is_anonymous;
struct die_info *current_die;
&& ! dwarf_attr (die, DW_AT_specification));
}
+/* Return the die giving the specification for DIE, if there is
+ one. */
+
+static struct die_info *
+die_specification (struct die_info *die)
+{
+ struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+
+ if (spec_attr == NULL)
+ return NULL;
+ else
+ return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+}
/* Free the line_header structure *LH, and any arrays and strings it
refers to. */
case DW_TAG_enumeration_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
- add_symbol_to_list (sym, list_in_scope);
- /* The semantics of C++ state that "struct foo { ... }" also
- defines a typedef for "foo". Synthesize a typedef symbol so
- that "ptype foo" works as expected. */
+ /* Make sure that the symbol includes appropriate enclosing
+ classes/namespaces in its name. These are calculated in
+ read_structure_scope, and the correct name is saved in
+ the type. */
+
if (cu_language == language_cplus)
{
- struct symbol *typedef_sym = (struct symbol *)
- obstack_alloc (&objfile->symbol_obstack,
- sizeof (struct symbol));
- *typedef_sym = *sym;
- SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym)) =
- obsavestring (DEPRECATED_SYMBOL_NAME (sym),
- strlen (DEPRECATED_SYMBOL_NAME (sym)),
- &objfile->type_obstack);
- add_symbol_to_list (typedef_sym, list_in_scope);
+ struct type *type = SYMBOL_TYPE (sym);
+
+ if (TYPE_TAG_NAME (type) != NULL)
+ {
+ /* FIXME: carlton/2003-11-10: Should this use
+ SYMBOL_SET_NAMES instead? (The same problem also
+ arises a further down in the function.) */
+ SYMBOL_LINKAGE_NAME (sym)
+ = obsavestring (TYPE_TAG_NAME (type),
+ strlen (TYPE_TAG_NAME (type)),
+ &objfile->symbol_obstack);
+ }
}
+
+ {
+ /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+ really ever be static objects: otherwise, if you try
+ to, say, break of a class's method and you're in a file
+ which doesn't mention that class, it won't work unless
+ the check for all static symbols in lookup_symbol_aux
+ saves you. See the OtherFileClass tests in
+ gdb.c++/namespace.exp. */
+
+ struct pending **list_to_add;
+
+ list_to_add = (list_in_scope == &file_symbols
+ && cu_language == language_cplus
+ ? &global_symbols : list_in_scope);
+
+ add_symbol_to_list (sym, list_to_add);
+
+ /* The semantics of C++ state that "struct foo { ... }" also
+ defines a typedef for "foo". Synthesize a typedef symbol so
+ that "ptype foo" works as expected. */
+ if (cu_language == language_cplus)
+ {
+ struct symbol *typedef_sym = (struct symbol *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (struct symbol));
+ *typedef_sym = *sym;
+ SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
+ if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
+ TYPE_NAME (SYMBOL_TYPE (sym)) =
+ obsavestring (SYMBOL_NATURAL_NAME (sym),
+ strlen (SYMBOL_NATURAL_NAME (sym)),
+ &objfile->type_obstack);
+ add_symbol_to_list (typedef_sym, list_to_add);
+ }
+ }
break;
case DW_TAG_typedef:
+ if (processing_has_namespace_info
+ && processing_current_prefix[0] != '\0')
+ {
+ SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+ processing_current_prefix,
+ "::",
+ name);
+ }
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+ add_symbol_to_list (sym, list_in_scope);
+ break;
case DW_TAG_base_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, list_in_scope);
break;
case DW_TAG_enumerator:
+ if (processing_has_namespace_info
+ && processing_current_prefix[0] != '\0')
+ {
+ SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+ processing_current_prefix,
+ "::",
+ name);
+ }
attr = dwarf_attr (die, DW_AT_const_value);
if (attr)
{
dwarf2_const_value (attr, sym, cu);
}
- add_symbol_to_list (sym, list_in_scope);
+ {
+ /* NOTE: carlton/2003-11-10: See comment above in the
+ DW_TAG_class_type, etc. block. */
+
+ struct pending **list_to_add;
+
+ list_to_add = (list_in_scope == &file_symbols
+ && cu_language == language_cplus
+ ? &global_symbols : list_in_scope);
+
+ add_symbol_to_list (sym, list_to_add);
+ }
break;
case DW_TAG_namespace:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
static void
read_type_die (struct die_info *die, struct dwarf2_cu *cu)
{
+ char *prefix = determine_prefix (die);
+ const char *old_prefix = processing_current_prefix;
+ struct cleanup *back_to = make_cleanup (xfree, prefix);
+ processing_current_prefix = prefix;
+
switch (die->tag)
{
case DW_TAG_class_type:
dwarf_tag_name (die->tag));
break;
}
+
+ processing_current_prefix = old_prefix;
+ do_cleanups (back_to);
+}
+
+/* Return the name of the namespace/class that DIE is defined
+ within, or NULL if we can't tell. The caller should xfree the
+ result. */
+
+static char *
+determine_prefix (struct die_info *die)
+{
+ struct die_info *parent;
+
+ if (cu_language != language_cplus)
+ return NULL;
+
+ parent = die->parent;
+
+ if (parent == NULL)
+ {
+ return (processing_has_namespace_info ? xstrdup ("") : NULL);
+ }
+ else
+ {
+ char *parent_prefix = determine_prefix (parent);
+ char *retval;
+
+ switch (parent->tag) {
+ case DW_TAG_namespace:
+ {
+ int dummy;
+
+ retval = typename_concat (parent_prefix,
+ namespace_name (parent, &dummy));
+ }
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ {
+ if (parent_prefix != NULL)
+ {
+ const char *parent_name = dwarf2_name (parent);
+
+ if (parent_name != NULL)
+ retval = typename_concat (parent_prefix, dwarf2_name (parent));
+ else
+ /* FIXME: carlton/2003-11-10: I'm not sure what the
+ best thing to do here is. */
+ retval = typename_concat (parent_prefix,
+ "<<anonymous class>>");
+ }
+ else
+ retval = class_name (parent);
+ }
+ break;
+ default:
+ retval = parent_prefix;
+ break;
+ }
+
+ if (retval != parent_prefix)
+ xfree (parent_prefix);
+ return retval;
+ }
+}
+
+/* Return a newly-allocated string formed by concatenating PREFIX,
+ "::", and SUFFIX, except that if PREFIX is NULL or the empty
+ string, just return a copy of SUFFIX. */
+
+static char *
+typename_concat (const char *prefix, const char *suffix)
+{
+ if (prefix == NULL || prefix[0] == '\0')
+ return xstrdup (suffix);
+ else
+ {
+ char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+
+ strcpy (retval, prefix);
+ strcat (retval, "::");
+ strcat (retval, suffix);
+
+ return retval;
+ }
+}
+
+/* Return a newly-allocated string giving the name of the class given
+ by DIE. */
+
+static char *
+class_name (struct die_info *die)
+{
+ struct die_info *child;
+ const char *name;
+
+ for (child = die->child; child != NULL; child = sibling_die (child))
+ {
+ if (child->tag == DW_TAG_subprogram)
+ return class_name_from_physname (dwarf2_linkage_name (child));
+ }
+
+ name = dwarf2_name (die);
+ if (name != NULL)
+ return xstrdup (name);
+ else
+ return xstrdup ("");
}
static struct type *
/* Perform non-arithmetic operations on values, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
static int check_field_in (struct type *, const char *);
-
static struct value *value_struct_elt_for_reference (struct type *domain,
int offset,
struct type *curtype,
char *name,
- struct type *intype);
+ struct type *intype,
+ enum noside noside);
static struct value *value_namespace_elt (const struct type *curtype,
- const char *name,
+ char *name,
enum noside noside);
+static struct value *value_maybe_namespace_elt (const struct type *curtype,
+ char *name,
+ enum noside noside);
+
static CORE_ADDR allocate_space_in_inferior (int);
static struct value *cast_into_complex (struct type *, struct value *);
{
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
- return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL);
+ return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL,
+ noside);
case TYPE_CODE_NAMESPACE:
return value_namespace_elt (curtype, name, noside);
default:
"pointers to member functions". This function is used
to resolve user expressions of the form "DOMAIN::NAME". */
-struct value *
+static struct value *
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
- struct type *intype)
+ struct type *intype,
+ enum noside noside)
{
struct type *t = curtype;
int i;
offset + base_offset,
TYPE_BASECLASS (t, i),
name,
- intype);
+ intype,
+ noside);
if (v)
return v;
}
- return 0;
+
+ /* As a last chance, pretend that CURTYPE is a namespace, and look
+ it up that way; this (frequently) works for types nested inside
+ classes. */
+
+ return value_maybe_namespace_elt (curtype, name, noside);
}
/* C++: Return the member NAME of the namespace given by the type
static struct value *
value_namespace_elt (const struct type *curtype,
- const char *name,
+ char *name,
enum noside noside)
{
+ struct value *retval = value_maybe_namespace_elt (curtype, name,
+ noside);
+
+ if (retval == NULL)
+ error ("No symbol \"%s\" in namespace \"%s\".", name,
+ TYPE_TAG_NAME (curtype));
+
+ return retval;
+}
+
+/* A helper function used by value_namespace_elt and
+ value_struct_elt_for_reference. It looks up NAME inside the
+ context CURTYPE; this works if CURTYPE is a namespace or if CURTYPE
+ is a class and NAME refers to a type in CURTYPE itself (as opposed
+ to, say, some base class of CURTYPE). */
+
+static struct value *
+value_maybe_namespace_elt (const struct type *curtype,
+ char *name,
+ enum noside noside)
+{
const char *namespace_name = TYPE_TAG_NAME (curtype);
struct symbol *sym;
- struct value *retval;
sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
get_selected_block (0), VAR_DOMAIN,
NULL);
if (sym == NULL)
- retval = NULL;
+ return NULL;
else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
&& (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
- retval = allocate_value (SYMBOL_TYPE (sym));
+ return allocate_value (SYMBOL_TYPE (sym));
else
- retval = value_of_variable (sym, get_selected_block (0));
-
- if (retval == NULL)
- error ("No symbol \"%s\" in namespace \"%s\".", name,
- TYPE_TAG_NAME (curtype));
-
- return retval;
+ return value_of_variable (sym, get_selected_block (0));
}
-
/* Given a pointer value V, find the real (RTTI) type
of the object it points to.
Other parameters FULL, TOP, USING_ENC as with value_rtti_type()