if (SYMBOL_CLASS (sym.symbol) == LOC_LABEL)
sym_type = 0;
else if (!SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (sym.symbol))
- sym_type = instance->convert_type (SYMBOL_TYPE (sym.symbol),
- GCC_CP_ACCESS_NONE);
+ sym_type = instance->convert_type (SYMBOL_TYPE (sym.symbol));
if (SYMBOL_DOMAIN (sym.symbol) == STRUCT_DOMAIN)
{
break;
}
- sym_type = instance->convert_type (type, GCC_CP_ACCESS_NONE);
+ sym_type = instance->convert_type (type);
instance->push_namespace ("");
// FIXME: push (and, after the call, pop) any other namespaces, if
// any, and drop the above when defining a class member. drop any
/* This type must previously have been converted,
or GCC will error with "definition of TYPE inside
template parameter list." */
- default_type = instance->convert_type (type,
- GCC_CP_ACCESS_NONE);
+ default_type = instance->convert_type (type);
}
gcc_type abstract_type
/* Get the argument's type. This type must also have been
previously defined (or declared) to prevent errors. */
- gcc_type abstract_type
- = instance->convert_type (ptype, GCC_CP_ACCESS_NONE);
+ gcc_type abstract_type = instance->convert_type (ptype);
defn->set_parameter_abstract_type (i, abstract_type);
if (defn->default_argument (i) != NULL)
case type_parameter:
{
gcc_type type
- = convert_type (SYMBOL_TYPE (arg_info->arguments[i]),
- GCC_CP_ACCESS_NONE);
+ = convert_type (SYMBOL_TYPE (arg_info->arguments[i]));
dest->elements[i].type = type;
}
{
case type_parameter:
case value_parameter:
- instance->convert_type (SYMBOL_TYPE (defn->default_argument (i)),
- GCC_CP_ACCESS_NONE);
+ instance->convert_type (SYMBOL_TYPE (defn->default_argument (i)));
break;
case template_parameter:
{
struct type *temp = TYPE_TARGET_TYPE (SYMBOL_TYPE (&tsym->base));
- return_type = m_instance->convert_type (temp, GCC_CP_ACCESS_NONE);
+ return_type = m_instance->convert_type (temp);
}
// Get the parameters' definitions, and put them into ARRAY.
{
// The parameter's type is a concrete type.
array.elements[i - artificials]
- = m_instance->convert_type (arg_type, GCC_CP_ACCESS_NONE);
+ = m_instance->convert_type (arg_type);
}
else
{
/* Get the defining class's type. This should already be in the
cache. */
- class_type = m_instance->convert_type (defn->parent_type (),
- GCC_CP_ACCESS_NONE);
+ class_type = m_instance->convert_type (defn->parent_type ());
// Add any virtuality flags.
if (TYPE_FN_FIELD_VIRTUAL_P (methods, defn->midx ()))
{
/* The type is defined inside another class(es). Convert that
type instead of defining this type. */
- convert_type (SYMBOL_TYPE (comp.bsymbol.symbol), GCC_CP_ACCESS_NONE);
+ convert_type (SYMBOL_TYPE (comp.bsymbol.symbol));
/* If the original type (passed in to us) is defined in a nested
class, the previous call will give us that type's gcc_type.
ccp_convert_reference (compile_cplus_instance *instance,
struct type *type)
{
- gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type),
- GCC_CP_ACCESS_NONE);
+ gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type));
/* !!keiths: GDB does not currently do anything with rvalue references.
[Except set the type code to TYPE_CODE_ERROR! */
ccp_convert_pointer (compile_cplus_instance *instance,
struct type *type)
{
- gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type),
- GCC_CP_ACCESS_NONE);
+ gcc_type target = instance->convert_type (TYPE_TARGET_TYPE (type));
return convert_pointer_base (instance, target);
}
static gcc_type
ccp_convert_array (compile_cplus_instance *instance, struct type *type)
{
- gcc_type element_type;
struct type *range = TYPE_INDEX_TYPE (type);
-
- element_type = instance->convert_type (TYPE_TARGET_TYPE (type),
- GCC_CP_ACCESS_NONE);
+ gcc_type element_type = instance->convert_type (TYPE_TARGET_TYPE (type));
if (TYPE_LOW_BOUND_KIND (range) != PROP_CONST)
{
instance->enter_scope (scope);
// Convert the typedef's real type.
- gcc_type typedef_type = instance->convert_type (check_typedef (type),
- GCC_CP_ACCESS_NONE);
+ gcc_type typedef_type = instance->convert_type (check_typedef (type));
instance->new_decl ("typedef", name,
GCC_CP_SYMBOL_TYPEDEF | nested_access,
continue;
field_type
- = instance->convert_type (TYPE_FIELD_TYPE (type, i),
- GCC_CP_ACCESS_NONE);
+ = instance->convert_type (TYPE_FIELD_TYPE (type, i));
if (field_is_static (&TYPE_FIELD (type, i)))
{
/* Convert a method type to its gcc representation. */
-static gcc_type __attribute__ ((used))
+static gcc_type
ccp_convert_method (compile_cplus_instance *instance,
struct type *parent_type, struct type *method_type)
{
/* Get the actual (proto)type of the method, as a function. */
func_type = ccp_convert_func (instance, method_type, 1);
- class_type = instance->convert_type (parent_type, GCC_CP_ACCESS_NONE);
+ class_type = instance->convert_type (parent_type);
quals = (enum gcc_cp_qualifiers) 0;
if (TYPE_CONST (method_type))
quals |= GCC_CP_QUALIFIER_CONST;
return result;
}
+// Convert a member or method pointer represented by TYPE.
+
+static gcc_type
+ccp_convert_memberptr (compile_cplus_instance *instance, struct type *type)
+{
+ struct type *containing_class = TYPE_SELF_TYPE (type);
+
+ if (containing_class == NULL)
+ return GCC_TYPE_NONE;
+
+ gcc_type class_type = instance->convert_type (containing_class);
+ gcc_type member_type = instance->convert_type (TYPE_TARGET_TYPE (type));
+
+ return instance->build_pointer_to_member_type (class_type, member_type);
+}
+
#define OPHASH1(A) ((uint32_t) A << 16)
#define OPHASH2(A,B) OPHASH1(A) | (uint32_t) B << 8
#define OPHASH3(A,B,C) OPHASH2(A,B) | (uint32_t) C
| (BASETYPE_VIA_VIRTUAL (type, i)
? GCC_CP_FLAG_BASECLASS_VIRTUAL
: GCC_CP_FLAG_BASECLASS_NOFLAG);
- bases.elements[i] = instance->convert_type (base_type,
- GCC_CP_ACCESS_NONE);
+ bases.elements[i] = instance->convert_type (base_type);
}
}
/* This approach means we can't make self-referential function
types. Those are impossible in C, though. */
- return_type = instance->convert_type (TYPE_TARGET_TYPE (type),
- GCC_CP_ACCESS_NONE);
+ return_type = instance->convert_type (TYPE_TARGET_TYPE (type));
array.n_elements = TYPE_NFIELDS (type);
array.elements = XNEWVEC (gcc_type, TYPE_NFIELDS (type));
else
{
array.elements[i - artificials]
- = instance->convert_type (TYPE_FIELD_TYPE (type, i),
- GCC_CP_ACCESS_NONE);
+ = instance->convert_type (TYPE_FIELD_TYPE (type, i));
}
}
gcc_cp_qualifiers_flags quals = (enum gcc_cp_qualifiers) 0;
gcc_type result;
- unqual_converted = instance->convert_type (unqual, GCC_CP_ACCESS_NONE);
+ unqual_converted = instance->convert_type (unqual);
if (TYPE_CONST (type))
quals |= GCC_CP_QUALIFIER_CONST;
ccp_convert_complex (compile_cplus_instance *instance,
struct type *type)
{
- gcc_type base = instance->convert_type (TYPE_TARGET_TYPE (type),
- GCC_CP_ACCESS_NONE);
+ gcc_type base = instance->convert_type (TYPE_TARGET_TYPE (type));
return instance->build_complex_type (base);
}
case TYPE_CODE_FUNC:
return ccp_convert_func (instance, type, 0);
-#if 0
case TYPE_CODE_METHOD:
- return ccp_convert_method (instance, type);
-#endif
+ return ccp_convert_method (instance, TYPE_SELF_TYPE (type), type);
+
+ case TYPE_CODE_MEMBERPTR:
+ case TYPE_CODE_METHODPTR:
+ return ccp_convert_memberptr (instance, type);
+ break;
case TYPE_CODE_INT:
return ccp_convert_int (instance, type);
{
DECLARE_FORWARD (push_namespace, name);
- return forward ("%s", name);
+ return forward ("\"%s\"", name);
}
// See description in gcc-cp-fe.def.
{
DECLARE_FORWARD (pop_namespace);
- return forward ("%s", opt_name);
+ return forward ("\"%s\"", opt_name);
}
// See description in gcc-cp-fe.def.
return forward ("for generic %s\n", generic);
}
+// See description in gcc-cp-fe.def.
+
+gcc_type
+compile_cplus_instance::build_pointer_to_member_type (gcc_type class_type,
+ gcc_type member_type)
+{
+ DECLARE_FORWARD (build_pointer_to_member_type, class_type, member_type);
+
+ return forward ("%lld %lld", class_type, member_type);
+}
+
#undef DECLARE_FORWARD
void _initialize_compile_cplus_types (void);
add it to INSTANCE's list of template definitions and scan for default
values. */
- void
- maybe_define_new_function_template (const struct symbol *sym,
- struct type *parent_type,
- int f_idx, int m_idx);
+ void maybe_define_new_function_template (const struct symbol *sym,
+ struct type *parent_type,
+ int f_idx, int m_idx);
/* If TYPE (with declaration name DECL_NAME) represents a concrete instance
of a new class template, note the new template definition. */
- void
- maybe_define_new_class_template (struct type *type, const char *decl_name);
+ void maybe_define_new_class_template (struct type *type,
+ const char *decl_name);
/* Find the generic template definition for TSYM or NULL if none was
found. */
- function_template_defn *
- find_function_template_defn (struct template_symbol *tsym);
+ function_template_defn *find_function_template_defn
+ (struct template_symbol *tsym);
/* Search for an existing class template definition based on TYPE.
Returns NULL if no template based on TYPE is known. */
If this type was defined in another type, NESTED_ACCESS should indicate
the accessibility of this type (or GCC_CP_ACCESS_NONE if not a nested
- type).
+ type). GCC_CP_ACCESS_NONE is the default nested access.
The new GCC type is returned. */
- gcc_type convert_type (struct type *type,
- enum gcc_cp_symbol_kind nested_access);
+ gcc_type convert_type
+ (struct type *type,
+ enum gcc_cp_symbol_kind nested_access = GCC_CP_ACCESS_NONE);
/* Factory method to create a new scope based on TYPE with name TYPE_NAME.
[TYPE_NAME could be TYPE_NAME or SYMBOL_NATURAL_NAME.]
compile_scope new_scope (const char *type_name, struct type *type);
- /* Enter the given NEW_SCOPE.
-
- Scopes are always pushed onto the internal stack of scopes, but they
- are only pushed to the plug-in when necessary. */
+ // Enter the given NEW_SCOPE.
void enter_scope (compile_scope &scope);
- /* Leave the current scope.
-
- Scopes are always removed from the internal stack of scopes, but they
- are only popped from the plug-in when necessary. */
+ // Leave the current scope.
void leave_scope ();
// !!keiths: YUCK!
// Plug-in forwards
+ gcc_type bool_type ();
+
+ gcc_decl build_add_enum_constant (gcc_type enum_type, const char *name,
+ unsigned long value);
+
+ gcc_type build_array_type (gcc_type element_type, int num_elements);
+
bool build_constant (gcc_type type, const char *name, unsigned long value,
const char *filename, unsigned int line_number);
- gcc_decl specialize_function_template (struct template_symbol *concrete,
- gcc_address address,
- const char *filename,
- unsigned int line_number);
+ gcc_type build_complex_type (gcc_type element_type);
- gcc_decl specialize_class_template (struct type *concrete,
- const char *filename,
- unsigned int line_number);
+ gcc_type build_function_type (gcc_type return_type,
+ const struct gcc_type_array *argument_types,
+ bool is_varargs);
- // DECL_DESC for debugging only
- gcc_decl new_decl (const char *decl_desc, const char *name,
- enum gcc_cp_symbol_kind sym_kind,
- gcc_type sym_type, const char *substitution_name,
- gcc_address address,
- const char *filename, unsigned int line_number);
+ gcc_type build_method_type (gcc_type class_type, gcc_type func_type,
+ enum gcc_cp_qualifiers quals,
+ enum gcc_cp_ref_qualifiers rquals);
- bool push_namespace (const char *name);
+ gcc_type build_qualified_type (gcc_type unqualified_type,
+ enum gcc_cp_qualifiers qualifiers);
- // NAME is for debugging only
- bool pop_namespace (const char *name);
+ gcc_type build_pointer_to_member_type (gcc_type class_type,
+ gcc_type member_type);
- gcc_type error (const char *message);
+ gcc_type build_pointer_type (gcc_type base_type);
gcc_type build_reference_type (gcc_type base_type,
enum gcc_cp_ref_qualifiers rquals);
- gcc_type build_pointer_type (gcc_type base_type);
-
gcc_type build_vla_array_type (gcc_type element_type,
const char *upper_bound_name);
gcc_type build_vector_type (gcc_type element_type, int num_elements);
- gcc_type build_array_type (gcc_type element_type, int num_elements);
-
- gcc_decl new_field (const char *field_name, gcc_type field_type,
- enum gcc_cp_symbol_kind field_flags,
- unsigned long bitsize, unsigned long bitpos);
+ gcc_type char_type ();
- gcc_type build_method_type (gcc_type class_type, gcc_type func_type,
- enum gcc_cp_qualifiers quals,
- enum gcc_cp_ref_qualifiers rquals);
+ gcc_type error (const char *message);
- // NAME only for debugging
- gcc_type start_class_definition (const char *name, gcc_decl typedecl,
- const struct gcc_vbase_array *base_classes,
- const char *filename,
- unsigned int line_number);
+ bool finish_enum_type (gcc_type enum_type);
// NAME for debugging
bool finish_record_or_union (const char *name, unsigned long size_in_bytes);
- gcc_type int_type (bool is_unsigned, unsigned long size_in_bytes,
- const char *builtin_name);
-
- gcc_type start_new_enum_type (const char *name,
- gcc_type underlying_int_type,
- enum gcc_cp_symbol_kind flags,
- const char *filename,
- unsigned int line_number);
-
- gcc_decl build_add_enum_constant (gcc_type enum_type, const char *name,
- unsigned long value);
-
- bool finish_enum_type (gcc_type enum_type);
-
- gcc_type build_function_type (gcc_type return_type,
- const struct gcc_type_array *argument_types,
- bool is_varargs);
-
- gcc_type char_type ();
-
gcc_type float_type (unsigned long size_in_bytes, const char *builtin_name);
- gcc_type void_type ();
-
- gcc_type bool_type ();
+ gcc_type int_type (bool is_unsigned, unsigned long size_in_bytes,
+ const char *builtin_name);
- gcc_type build_qualified_type (gcc_type unqualified_type,
- enum gcc_cp_qualifiers qualifiers);
+ gcc_expr literal_expr (gcc_type type, unsigned long value);
- gcc_type build_complex_type (gcc_type element_type);
+ // DECL_DESC for debugging only
+ gcc_decl new_decl (const char *decl_desc, const char *name,
+ enum gcc_cp_symbol_kind sym_kind,
+ gcc_type sym_type, const char *substitution_name,
+ gcc_address address,
+ const char *filename, unsigned int line_number);
- gcc_expr literal_expr (gcc_type type, unsigned long value);
+ gcc_decl new_field (const char *field_name, gcc_type field_type,
+ enum gcc_cp_symbol_kind field_flags,
+ unsigned long bitsize, unsigned long bitpos);
gcc_type new_template_typename_parm (const char *id, bool pack_p,
gcc_type default_type,
const char *filename,
unsigned int line_number);
+ // NAME is for debugging only
+ bool pop_namespace (const char *name);
+
+ bool push_namespace (const char *name);
+
+ gcc_decl specialize_class_template (struct type *concrete,
+ const char *filename,
+ unsigned int line_number);
+
+ gcc_decl specialize_function_template (struct template_symbol *concrete,
+ gcc_address address,
+ const char *filename,
+ unsigned int line_number);
+
+ // NAME only for debugging
+ gcc_type start_class_definition (const char *name, gcc_decl typedecl,
+ const struct gcc_vbase_array *base_classes,
+ const char *filename,
+ unsigned int line_number);
+
+ gcc_type start_new_enum_type (const char *name,
+ gcc_type underlying_int_type,
+ enum gcc_cp_symbol_kind flags,
+ const char *filename,
+ unsigned int line_number);
+
// GENERIC only for debugging
bool start_new_template_decl (const char *generic);
+ gcc_type void_type ();
+
+
private:
// Enumerate the template arguments of template DEFN into DEST.
If the given method should be ignored (not defined to the plug-in),
IGNORE will be true. */
- extern const char *
- maybe_canonicalize_special_function (const char *field_name,
- const struct fn_field *method_field,
- const struct type *method_type,
- char **outname,
- bool *ignore);
+ const char *maybe_canonicalize_special_function
+ (const char *field_name, const struct fn_field *method_field,
+ const struct type *method_type, char **outname, bool *ignore);
};
/* A callback suitable for use as the GCC C++ symbol oracle. */
#include "compile-internal.h"
#include <string>
-#include <tr1/unordered_map>
+#include <unordered_map>
/* Debugging flag for the "compile" family of commands. */
// Returns the GCC options to be passed during compilation.
- const std::string &
- gcc_target_options () const
+ const std::string &gcc_target_options () const
{
return m_gcc_target_options;
}
unsigned int version () const;
-
// Set the plug-in's verbosity level.
void set_verbose (int level);
void set_driver_filename (const char *filename);
- // Set the regular expression used to match the configury triplet
- // prefix to the compiler.
+ /* Set the regular expression used to match the configury triplet
+ prefix to the compiler. */
void set_triplet_regexp (const char *regexp);
and error tracking. */
typedef std::pair<struct type *, gcc_type> type_map_item_t;
- typedef std::tr1::unordered_map<struct type *, gcc_type> type_map_t;
+ typedef std::unordered_map<struct type *, gcc_type> type_map_t;
typedef std::pair<const struct symbol *, std::string> symbol_err_map_item_t;
- typedef std::tr1::unordered_map<const struct symbol *, std::string> symbol_err_map_t;
+ typedef std::unordered_map<const struct symbol *, std::string>
+ symbol_err_map_t;
- /* The GCC front end. */
+ // The GCC front end.
struct gcc_base_context *m_gcc_fe;
- /* The "scope" of this compilation. */
+ // The "scope" of this compilation.
enum compile_i_scope_types m_scope;
- /* The block in which an expression is being parsed. */
+ // The block in which an expression is being parsed.
const struct block *m_block;
/* Specify "-std=gnu11", "-std=gnu++11" or similar. These options are put
symbol_err_map_t m_symbol_err_map;
};
-/* Define header and footers for different scopes. */
+// Define header and footers for different scopes.
/* A simple scope just declares a function named "_gdb_expr", takes no
arguments and returns no value. */
#define COMPILE_I_EXPR_VAL "__gdb_expr_val"
#define COMPILE_I_EXPR_PTR_TYPE "__gdb_expr_ptr_type"
-/* A "type" to indicate a NULL type. */
-#define GCC_TYPE_NONE ((gcc_type) -1)
+// A "type" to indicate a NULL type.
+
+const gcc_type GCC_TYPE_NONE = (gcc_type) -1;
/* Call gdbarch_register_name (GDBARCH, REGNUM) and convert its result
to a form suitable for the compiler source. The register names
return val; // = 85
}
+typedef int A::*PMI;
+
int
main (void)
{
A a;
int var = 1234;
+ PMI pmi = &A::public_;
- return get_values (a); // break here
+ return a.*pmi + get_values (a); // break here
}
-# Copyright 2015, 2016 Free Software Foundation, Inc.
+# Copyright 2015-2016 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
CompileExpression::add_exp "A::s_protected_ = N::AB; var = A::s_protected_;" 21
CompileExpression::add_exp "A::s_private_ = E_B; var = A::s_private_;" 11
CompileExpression::add_exp "N::ANON_E ae = N::AD; var = ae;" 23
+CompileExpression::add_imp {a.*pmi} 1
+CompileExpression::add_exp {a.public_ = 2; var = a.*pmi; a.public_ = 1} 2
CompileExpression::run_tests "code"
#CompileExpression::run_tests "print"
# Test some compilation failures
set failed {\r\nCompilation failed\.}
+# !!keiths: This should actually really work...
gdb_test "compile code a.s_public_ = E_B" \
".*assignment of read-only variable 'A::s_public_'$failed"
+
gdb_test "compile code get_values ()" \
".*too few arguments to function.*$failed"
+
gdb_test "compile code ATYPE i;" \
".*.ATYPE. was not declared in this scope$failed"
-/* Copyright 2015 Free Software Foundation, Inc.
+/* Copyright 2015, 2016 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
class A
{
public:
+ typedef int ATYPE;
+
A (void) : a_ (21) {}
- int get_var (void) { return a_; }
- int get_var (unsigned long a) { return 100; }
- int get_var (int a) { return 101; }
- int get_var (float a) { return 102; }
- int get_var (void *a) { return 103;}
- int get_var (A& lr) { return 104; }
- int get_var (A const& lr) { return 105; }
+ ATYPE get_var (void) { return a_; }
+ ATYPE get_var (unsigned long a) { return 100; }
+ ATYPE get_var (ATYPE a) { return 101; }
+ ATYPE get_var (float a) { return 102; }
+ ATYPE get_var (void *a) { return 103;}
+ ATYPE get_var (A& lr) { return 104; }
+ ATYPE get_var (A const& lr) { return 105; }
- int get_var1 (int n) { return a_ << n; }
- int get_var2 (int incr, unsigned n) { return (a_ + incr) << n; }
+ ATYPE get_var1 (int n) { return a_ << n; }
+ ATYPE get_var2 (int incr, unsigned n) { return (a_ + incr) << n; }
- static int get_1 (int a) { return a + 1; }
- static int get_2 (int a, int b) { return a + b + 2; }
+ static ATYPE get_1 (int a) { return a + 1; }
+ static ATYPE get_2 (int a, int b) { return a + b + 2; }
- friend int get_value (const A*);
+ friend ATYPE get_value (const A*);
private:
- int a_;
+ ATYPE a_;
};
-static int
-get_value (int a)
+static A::ATYPE
+get_value (A::ATYPE a)
{
return a;
}
-static int
+static A::ATYPE
get_value (const A* a)
{
return a->a_;
}
-static int
+static A::ATYPE
get_value (void)
{
return 200;
}
+typedef int (A::*PMF) (A::ATYPE);
+
int
main (void)
{
unsigned long ul = 0xdeadbeef;
A const* ac = a;
+ PMF pmf = &A::get_var;
+ PMF *pmf_p = &pmf;
+
var -= a->get_var (); // break here
var -= a->get_var (1);
var -= a->get_var (ul);
var -= a->get_var (*ac);
var -= a->get_var1 (1);
var -= a->get_var2 (1, 2);
+ var += (a->*pmf) (1);
+ var -= (a->**pmf_p) (1);
+
return var - A::get_1 (1) + A::get_2 (1, 2) + get_value ()
+ get_value (get_value ()) + get_value (a);
}
-# Copyright 2015 Free Software Foundation, Inc.
+# Copyright 2015-2016 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
CompileExpression::add_imp "get_value ()" 200
CompileExpression::add_imp "get_value (a)" 21
CompileExpression::add_imp "get_value (get_value ())" 200
+CompileExpression::add_imp {(a->*pmf) (1)} 101
+CompileExpression::add_exp {pmf = &A::get_var1; var = (a->*pmf) (2); pmf = &A::get_var} 84
+CompileExpression::add_imp {(a->**pmf_p) (1)} 101
+
CompileExpression::run_tests "code"
#CompileExpression::run_tests "print"