From 92ff8bbc95c05e8926897591f90f8aba6b72082d Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Mon, 7 Nov 2016 12:53:33 -0800 Subject: [PATCH] More cleanups, implement PMF/PMI. - compile_cplus_instance::convert_type default nested_access to GCC_CP_ACCESS_NONE. Change all callers. - Formatting and comments cleanups. - Implement PMI/F, convert_ptr_to_memberptr, add tests - tr1/unordered_map -> unordered_map - Fix typo CompileExpression::do_tests. Do not regexp-ify expected result. --- gdb/compile/compile-cplus-symbols.c | 5 +- gdb/compile/compile-cplus-templates.c | 19 +- gdb/compile/compile-cplus-types.c | 77 +++++---- gdb/compile/compile-cplus.h | 163 +++++++++--------- gdb/compile/compile-internal.h | 28 +-- gdb/testsuite/gdb.compile/cp-simple-member.cc | 5 +- .../gdb.compile/cp-simple-member.exp | 7 +- gdb/testsuite/gdb.compile/cp-simple-method.cc | 46 +++-- .../gdb.compile/cp-simple-method.exp | 6 +- 9 files changed, 193 insertions(+), 163 deletions(-) diff --git a/gdb/compile/compile-cplus-symbols.c b/gdb/compile/compile-cplus-symbols.c index 6e9ad2651bd..431d59986b8 100644 --- a/gdb/compile/compile-cplus-symbols.c +++ b/gdb/compile/compile-cplus-symbols.c @@ -64,8 +64,7 @@ convert_one_symbol (compile_cplus_instance *instance, 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) { @@ -388,7 +387,7 @@ convert_symbol_bmsym (compile_cplus_instance *instance, 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 diff --git a/gdb/compile/compile-cplus-templates.c b/gdb/compile/compile-cplus-templates.c index 84e5b6ec274..ef7c9fa1ced 100644 --- a/gdb/compile/compile-cplus-templates.c +++ b/gdb/compile/compile-cplus-templates.c @@ -762,8 +762,7 @@ define_template_parameters_generic /* 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 @@ -780,8 +779,7 @@ define_template_parameters_generic /* 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) @@ -858,8 +856,7 @@ compile_cplus_instance::enumerate_template_arguments 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; } @@ -903,8 +900,7 @@ define_default_template_parameter_types { 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: @@ -1174,7 +1170,7 @@ class function_template_definer { 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. @@ -1208,7 +1204,7 @@ class function_template_definer { // 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 { @@ -1238,8 +1234,7 @@ class function_template_definer /* 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 ())) diff --git a/gdb/compile/compile-cplus-types.c b/gdb/compile/compile-cplus-types.c index 9ac23d23eb0..26ea1519120 100644 --- a/gdb/compile/compile-cplus-types.c +++ b/gdb/compile/compile-cplus-types.c @@ -414,7 +414,7 @@ compile_cplus_instance::new_scope (const char *type_name, struct type *type) { /* 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. @@ -479,8 +479,7 @@ static 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! */ @@ -502,8 +501,7 @@ static gcc_type 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); } @@ -513,11 +511,8 @@ ccp_convert_pointer (compile_cplus_instance *instance, 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) { @@ -598,8 +593,7 @@ ccp_convert_typedef (compile_cplus_instance *instance, 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, @@ -671,8 +665,7 @@ ccp_convert_struct_or_union_members (compile_cplus_instance *instance, 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))) { @@ -751,7 +744,7 @@ ccp_convert_struct_or_union_members (compile_cplus_instance *instance, /* 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) { @@ -762,7 +755,7 @@ ccp_convert_method (compile_cplus_instance *instance, /* 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; @@ -775,6 +768,22 @@ ccp_convert_method (compile_cplus_instance *instance, 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 @@ -1389,8 +1398,7 @@ ccp_convert_struct_or_union (compile_cplus_instance *instance, | (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); } } @@ -1517,8 +1525,7 @@ ccp_convert_func (compile_cplus_instance *instance, struct type *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)); @@ -1533,8 +1540,7 @@ ccp_convert_func (compile_cplus_instance *instance, struct type *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)); } } @@ -1614,7 +1620,7 @@ ccp_convert_qualified (compile_cplus_instance *instance, 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; @@ -1632,8 +1638,7 @@ static gcc_type 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); } @@ -1721,10 +1726,13 @@ convert_type_cplus_basic (compile_cplus_instance *instance, 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); @@ -1960,7 +1968,7 @@ compile_cplus_instance::push_namespace (const char *name) { DECLARE_FORWARD (push_namespace, name); - return forward ("%s", name); + return forward ("\"%s\"", name); } // See description in gcc-cp-fe.def. @@ -1970,7 +1978,7 @@ compile_cplus_instance::pop_namespace (const char *opt_name) { DECLARE_FORWARD (pop_namespace); - return forward ("%s", opt_name); + return forward ("\"%s\"", opt_name); } // See description in gcc-cp-fe.def. @@ -2261,6 +2269,17 @@ compile_cplus_instance::start_new_template_decl (const char *generic) 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); diff --git a/gdb/compile/compile-cplus.h b/gdb/compile/compile-cplus.h index 575c1c717f6..1edc05591dc 100644 --- a/gdb/compile/compile-cplus.h +++ b/gdb/compile/compile-cplus.h @@ -120,22 +120,21 @@ namespace compile 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. */ @@ -154,12 +153,13 @@ namespace compile 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.] @@ -171,110 +171,79 @@ namespace compile 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, @@ -286,9 +255,38 @@ namespace compile 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. @@ -358,12 +356,9 @@ namespace compile 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. */ diff --git a/gdb/compile/compile-internal.h b/gdb/compile/compile-internal.h index 209d7534e02..018b0bafbca 100644 --- a/gdb/compile/compile-internal.h +++ b/gdb/compile/compile-internal.h @@ -22,7 +22,7 @@ #include "compile-internal.h" #include -#include +#include /* Debugging flag for the "compile" family of commands. */ @@ -52,8 +52,7 @@ public: // 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; } @@ -86,7 +85,6 @@ public: unsigned int version () const; - // Set the plug-in's verbosity level. void set_verbose (int level); @@ -95,8 +93,8 @@ public: 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); @@ -154,17 +152,18 @@ protected: and error tracking. */ typedef std::pair type_map_item_t; - typedef std::tr1::unordered_map type_map_t; + typedef std::unordered_map type_map_t; typedef std::pair symbol_err_map_item_t; - typedef std::tr1::unordered_map symbol_err_map_t; + typedef std::unordered_map + 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 @@ -178,7 +177,7 @@ protected: 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. */ @@ -191,8 +190,9 @@ protected: #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 diff --git a/gdb/testsuite/gdb.compile/cp-simple-member.cc b/gdb/testsuite/gdb.compile/cp-simple-member.cc index 053a627c3b4..9278088468c 100644 --- a/gdb/testsuite/gdb.compile/cp-simple-member.cc +++ b/gdb/testsuite/gdb.compile/cp-simple-member.cc @@ -70,11 +70,14 @@ get_values (const A& a) 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 } diff --git a/gdb/testsuite/gdb.compile/cp-simple-member.exp b/gdb/testsuite/gdb.compile/cp-simple-member.exp index 4c7c598c860..cd1af8aae9d 100644 --- a/gdb/testsuite/gdb.compile/cp-simple-member.exp +++ b/gdb/testsuite/gdb.compile/cp-simple-member.exp @@ -1,4 +1,4 @@ -# 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 @@ -55,15 +55,20 @@ CompileExpression::add_exp "myenum me = E_B; var = me;" 11 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" diff --git a/gdb/testsuite/gdb.compile/cp-simple-method.cc b/gdb/testsuite/gdb.compile/cp-simple-method.cc index e2f48393f0e..c3c99696df6 100644 --- a/gdb/testsuite/gdb.compile/cp-simple-method.cc +++ b/gdb/testsuite/gdb.compile/cp-simple-method.cc @@ -1,4 +1,4 @@ -/* 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 @@ -19,45 +19,49 @@ static int get_value (const A* a); 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) { @@ -67,6 +71,9 @@ 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); @@ -76,6 +83,9 @@ main (void) 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); } diff --git a/gdb/testsuite/gdb.compile/cp-simple-method.exp b/gdb/testsuite/gdb.compile/cp-simple-method.exp index dabcef53d3a..6a18e51a718 100644 --- a/gdb/testsuite/gdb.compile/cp-simple-method.exp +++ b/gdb/testsuite/gdb.compile/cp-simple-method.exp @@ -1,4 +1,4 @@ -# 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 @@ -60,5 +60,9 @@ CompileExpression::add_imp "a->get_var2 (a->get_var (), A::get_1 (2));" 336 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" -- 2.47.3