diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-01-31 01:02:03 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-01-31 01:02:03 +0000 |
commit | 37af486a23dbed5ff5003392c42495f4b68afb71 (patch) | |
tree | 3901a07d4c4dde00dbe21a5d032c741cfc2aaaa2 /gcc/cp | |
parent | 470672abaafa1c83bba7d6b1972c17096eaa9c65 (diff) | |
download | gcc-37af486a23dbed5ff5003392c42495f4b68afb71.tar.gz |
Introduce C++ support in libcc1
Extend libcc1's with an API for C++ support.
Extend libcc1's C API to distinguish between integral types with the
same width, as in C++. Likewise for float types.
Export small bits of functionality from the C++ front-end for use in
libcc1. Add support for the C++ front-end to look up names and
addresses using a libcc1-registered binding oracle. Add support for
global friends.
for gcc/cp/ChangeLog
Introduce C++ support in libcc1.
* cp-tree.h (struct lang_identifier): Add oracle_looked_up.
(ansi_opname): Rename to...
(cp_operator_id): ... this. Adjust all callers.
(ansi_assopname): Rename to...
(cp_assignment_operator_id): ... this. Adjust all callers.
(cp_literal_operator_id): Declare.
(set_global_friend): Declare.
(is_global_friend): Declare.
(enum cp_oracle_request): New type.
(cp_binding_oracle_function): New type.
(cp_binding_oracle): Declare.
(cp_finish_injected_record_type): Declare.
* friend.c (global_friend): New var.
(set_global_friend): New fn.
(is_global_friend): New fn.
(is_friend): Call is_global_friend.
* name-lookup.c (cp_binding_oracle): New var.
(query_oracle): New fn.
(qualified_lookup_using_namespace): Call query_oracle.
(lookup_name_real_1): Likewise.
* parser.c (cp_literal_operator_id): Drop static.
* search.c (friend_accessible_p): Call is_global_friend.
* semantics.c (is_this_parameter): Accept a variable if the
binding oracle is enabled.
for include/ChangeLog
Introduce C++ support in libcc1.
* gcc-c-fe.def (int_type_v0): Rename from...
(int_type): ... this. Introduce new version.
(float_type_v0): Rename from...
(float_type): ... this. Introduce new version.
(char_type): New.
* gcc-c-interface.h (gcc_c_api_version): Add GCC_C_FE_VERSION_1.
(gcc_type_array): Move...
* gcc-interface.h: ... here.
* gcc-cp-fe.def: New.
* gcc-cp-interface.h: New.
for libcc1/ChangeLog
Introduce C++ support.
* Makefile.am (AM_CPPFLAGS): Move some -I flags to...
(CPPFLAGS_FOR_C_FAMILY, CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): ...
new macros.
(plugin_LTLIBRARIES): Add libcp1plugin.la.
(BUILT_SOURCES, MOSTLYCLEANFILES): Add...
(cp-compiler-name.h): ... this. New.
(c-compiler-name.h): Rename all over from...
(compiler-name.h): ... this. Create it atomically.
(marshall_c_source, marshall_cxx_source): New macros.
(libcc1plugin_la_SOURCES): Rename plugin.cc to libcc1plugin.cc.
Add marshall_c_source expansion.
(libcc1plugin.lo_CPPFLAGS): New macro.
(libcp1plugin_la_LDFLAGS): Likewise.
(libcp1plugin_la_SOURCES): Likewise.
(libcp1plugin.lo_CPPFLAGS): Likewise.
(libcp1plugin_la_LIBADD): Likewise.
(libcp1plugin_la_DEPENDENCIES): Likewise.
(libcp1plugin_la_LINK): Likewise.
(libcc1_la_SOURCES): Added marshall_c_source and
marshall_cxx_source expansions.
* Makefile.in: Rebuild.
* compiler-name.h: Rename all over to...
* c-compiler-name.h: ... this. Define C_COMPILER_NAME instead
of COMPILER_NAME.
* plugin.cc: Rename all over to...
* libcc1plugin.cc: ... this. Include marshall-c.hh.
(address_rewriter): Drop cleaning up of VLA sizes.
(plugin_build_decl): Mark decls as external.
(plugin_tagbind): Propagate name to all variants.
(build_anonymous_node): New.
(plugin_build_record_type): Use it instead of make_node.
(plugin_build_union_type): Likewise.
(plugin_build_enum_type): Likewise.
(plugin_finish_record_or_union): Update all type variants.
(safe_lookup_builtin_type): New.
(plugin_int_check): Factor out of, and add checks to, ...
(plugin_int_type): ... this. Rename to...
(plugin_int_type_v0): ... this.
(plugin_int_type): New interface, new implementation.
(plugin_char_type): New.
(plugin_float_type_v0): Rename from...
(plugin_float_type): ... this. New interface, new implementation.
(plugin_init): Bump handshake version.
* libcc1.cc: Include marshall-c.hh. Drop gcc-interface.h.
(call_binding_oracle): Rename to...
(c_call_binding_oracle): ... this, into anonymous namespace.
(call_symbol_address): Rename to...
(c_call_symbol_address): ... this, likewise.
(GCC_METHOD#): Move methods into cc1plugin::c:: namespace.
(libcc1::compiler::find): Refer to C_COMPILER_NAME.
(fork_exec): Bump to GCC_C_FE_VERSION_1.
(libcc1_compile): Prefix callbacks with c_.
(gcc_c_fe_context): Accept GCC_C_FE_VERSION_1.
* libcc1.sym: Export gcc_cp_fe_context.
* libcp1.cc: New, mostly copied and adjusted from libcc1.cc.
* libcp1plugin.cc: New, initially copied from libcc1plugin.cc.
* libcp1plugin.sym: New.
* marshall-c.hh: New. Move C-specific types from...
* marshall.cc: ... this.
(cc1_plugin::marshall_array_start): New.
(cc1_plugin::marshall_array_elmts): New.
(cc1_plugin::marshall for gcc_type_array): Use the above.
(cc1_plugin::unmarshall_array_start): New.
(cc1_plugin::unmarshall_array_elmts): New.
(cc1_plugin::unmarshall for gcc_type_array): Use the above.
* marshall.hh: Declare the new array building blocks.
Drop C-specific unmarshall declarations.
* marshall-cp.hh: New.
* names.cc (GCC_METHOD#): Add LANG:: to method names.
(LANG): Define while including gcc-c-fe.def and gcc-cp-fe.def.
* names.hh: Include gcc-c-fe.def and gcc-cp-fe.def in the
corresponding namespaces.
* rpc.hh: Don't include marshall.hh.
[GCC_CP_INTERFACE_H] (argument_wrapper): Specialize for
gcc_vbase_array, gcc_cp_template_args, gcc_cp_function_args.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@245051 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/cp/call.c | 14 | ||||
-rw-r--r-- | gcc/cp/class.c | 10 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 40 | ||||
-rw-r--r-- | gcc/cp/decl.c | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/friend.c | 43 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 2 | ||||
-rw-r--r-- | gcc/cp/lex.c | 2 | ||||
-rw-r--r-- | gcc/cp/method.c | 10 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 27 | ||||
-rw-r--r-- | gcc/cp/parser.c | 103 | ||||
-rw-r--r-- | gcc/cp/search.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 2 |
16 files changed, 215 insertions, 88 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1f31731bc69..18732c927e3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,31 @@ +2017-01-30 Alexandre Oliva <aoliva@redhat.com> + + Introduce C++ support in libcc1. + * cp-tree.h (struct lang_identifier): Add oracle_looked_up. + (ansi_opname): Rename to... + (cp_operator_id): ... this. Adjust all callers. + (ansi_assopname): Rename to... + (cp_assignment_operator_id): ... this. Adjust all callers. + (cp_literal_operator_id): Declare. + (set_global_friend): Declare. + (is_global_friend): Declare. + (enum cp_oracle_request): New type. + (cp_binding_oracle_function): New type. + (cp_binding_oracle): Declare. + (cp_finish_injected_record_type): Declare. + * friend.c (global_friend): New var. + (set_global_friend): New fn. + (is_global_friend): New fn. + (is_friend): Call is_global_friend. + * name-lookup.c (cp_binding_oracle): New var. + (query_oracle): New fn. + (qualified_lookup_using_namespace): Call query_oracle. + (lookup_name_real_1): Likewise. + * parser.c (cp_literal_operator_id): Drop static. + * search.c (friend_accessible_p): Call is_global_friend. + * semantics.c (is_this_parameter): Accept a variable if the + binding oracle is enabled. + 2017-01-27 Jason Merrill <jason@redhat.com> PR c++/78771 - ICE with inherited constructor. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 8030d7ebb0b..6533214799d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4426,7 +4426,7 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain) if (TYPE_BINFO (type)) { - fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname (CALL_EXPR), 1); + fns = lookup_fnfields (TYPE_BINFO (type), cp_operator_id (CALL_EXPR), 1); if (fns == error_mark_node) return error_mark_node; } @@ -5136,7 +5136,7 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3, add_builtin_candidates (&candidates, COND_EXPR, NOP_EXPR, - ansi_opname (COND_EXPR), + cp_operator_id (COND_EXPR), args, LOOKUP_NORMAL, complain); @@ -5559,10 +5559,10 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, { code2 = TREE_CODE (arg3); arg3 = NULL_TREE; - fnname = ansi_assopname (code2); + fnname = cp_assignment_operator_id (code2); } else - fnname = ansi_opname (code); + fnname = cp_operator_id (code); arg1 = prep_operand (arg1); @@ -6167,7 +6167,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, type = strip_array_types (TREE_TYPE (TREE_TYPE (addr))); - fnname = ansi_opname (code); + fnname = cp_operator_id (code); if (CLASS_TYPE_P (type) && COMPLETE_TYPE_P (complete_type (type)) @@ -8283,7 +8283,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, || name == complete_dtor_identifier || name == base_dtor_identifier || name == deleting_dtor_identifier - || name == ansi_assopname (NOP_EXPR)); + || name == cp_assignment_operator_id (NOP_EXPR)); if (TYPE_P (binfo)) { /* Resolve the name. */ @@ -8311,7 +8311,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args, if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (instance), BINFO_TYPE (binfo))) { - if (name != ansi_assopname (NOP_EXPR)) + if (name != cp_assignment_operator_id (NOP_EXPR)) /* For constructors and destructors, either the base is non-virtual, or it is virtual but we are doing the conversion from a constructor or destructor for the diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 03a973084e5..d99ebcdc7df 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3254,7 +3254,7 @@ static tree dfs_declare_virt_assop_and_dtor (tree binfo, void *data) { tree bv, fn, t = (tree)data; - tree opname = ansi_assopname (NOP_EXPR); + tree opname = cp_assignment_operator_id (NOP_EXPR); gcc_assert (t && CLASS_TYPE_P (t)); gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO); @@ -5349,7 +5349,7 @@ vbase_has_user_provided_move_assign (tree type) { /* Does the type itself have a user-provided move assignment operator? */ for (tree fns - = lookup_fnfields_slot_nolazy (type, ansi_assopname (NOP_EXPR)); + = lookup_fnfields_slot_nolazy (type, cp_assignment_operator_id (NOP_EXPR)); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); @@ -5513,7 +5513,7 @@ type_has_move_assign (tree t) lazily_declare_fn (sfk_move_assignment, t); } - for (fns = lookup_fnfields_slot_nolazy (t, ansi_assopname (NOP_EXPR)); + for (fns = lookup_fnfields_slot_nolazy (t, cp_assignment_operator_id (NOP_EXPR)); fns; fns = OVL_NEXT (fns)) if (move_fn_p (OVL_CURRENT (fns))) return true; @@ -5558,7 +5558,7 @@ type_has_user_declared_move_assign (tree t) if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) return false; - for (fns = lookup_fnfields_slot_nolazy (t, ansi_assopname (NOP_EXPR)); + for (fns = lookup_fnfields_slot_nolazy (t, cp_assignment_operator_id (NOP_EXPR)); fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns); @@ -5679,7 +5679,7 @@ type_requires_array_cookie (tree type) the array to the deallocation function, so we will need to store a cookie. */ fns = lookup_fnfields (TYPE_BINFO (type), - ansi_opname (VEC_DELETE_EXPR), + cp_operator_id (VEC_DELETE_EXPR), /*protect=*/0); /* If there are no `operator []' members, or the lookup is ambiguous, then we don't need a cookie. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f412ddd6e4a..a744d8372bf 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -332,6 +332,7 @@ struct GTY(()) lang_identifier { cxx_binding *bindings; tree class_template_info; tree label_value; + bool oracle_looked_up; }; /* Return a typed pointer version of T if it designates a @@ -1530,15 +1531,17 @@ struct GTY(()) language_function { /* True if NAME is the IDENTIFIER_NODE for an overloaded "operator new" or "operator delete". */ #define NEW_DELETE_OPNAME_P(NAME) \ - ((NAME) == ansi_opname (NEW_EXPR) \ - || (NAME) == ansi_opname (VEC_NEW_EXPR) \ - || (NAME) == ansi_opname (DELETE_EXPR) \ - || (NAME) == ansi_opname (VEC_DELETE_EXPR)) + ((NAME) == cp_operator_id (NEW_EXPR) \ + || (NAME) == cp_operator_id (VEC_NEW_EXPR) \ + || (NAME) == cp_operator_id (DELETE_EXPR) \ + || (NAME) == cp_operator_id (VEC_DELETE_EXPR)) -#define ansi_opname(CODE) \ +#define cp_operator_id(CODE) \ (operator_name_info[(int) (CODE)].identifier) -#define ansi_assopname(CODE) \ +#define cp_assignment_operator_id(CODE) \ (assignment_operator_name_info[(int) (CODE)].identifier) +/* In parser.c. */ +extern tree cp_literal_operator_id (const char *); /* TRUE if a tree code represents a statement. */ extern bool statement_code_p[MAX_TREE_CODES]; @@ -6027,6 +6030,9 @@ extern void make_friend_class (tree, tree, bool); extern void add_friend (tree, tree, bool); extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool); +extern void set_global_friend (tree); +extern bool is_global_friend (tree); + /* in init.c */ extern tree expand_member_init (tree); extern void emit_mem_initializers (tree); @@ -6944,6 +6950,25 @@ extern void suggest_alternatives_for (location_t, tree, bool); extern bool suggest_alternative_in_explicit_scope (location_t, tree, tree); extern tree strip_using_decl (tree); +/* Tell the binding oracle what kind of binding we are looking for. */ + +enum cp_oracle_request +{ + CP_ORACLE_IDENTIFIER +}; + +/* If this is non-NULL, then it is a "binding oracle" which can lazily + create bindings when needed by the C compiler. The oracle is told + the name and type of the binding to create. It can call pushdecl + or the like to ensure the binding is visible; or do nothing, + leaving the binding untouched. c-decl.c takes note of when the + oracle has been called and will not call it again if it fails to + create a given binding. */ + +typedef void cp_binding_oracle_function (enum cp_oracle_request, tree identifier); + +extern cp_binding_oracle_function *cp_binding_oracle; + /* in constraint.cc */ extern void init_constraint_processing (); extern bool constraint_p (tree); @@ -7009,6 +7034,9 @@ extern void diagnose_constraints (location_t, tree, tree); extern tree decompose_conclusions (tree); extern bool subsumes (tree, tree); +/* In class.c */ +extern void cp_finish_injected_record_type (tree); + /* in vtable-class-hierarchy.c */ extern void vtv_compute_class_hierarchy_transitive_closure (void); extern void vtv_generate_init_routine (void); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 44aefd82b73..9bdfd4ff64b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4564,7 +4564,7 @@ static tree push_cp_library_fn (enum tree_code operator_code, tree type, int ecf_flags) { - tree fn = build_cp_library_fn (ansi_opname (operator_code), + tree fn = build_cp_library_fn (cp_operator_id (operator_code), operator_code, type, ecf_flags); pushdecl (fn); @@ -12937,12 +12937,12 @@ grok_op_properties (tree decl, bool complain) do { #define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \ - if (ansi_opname (CODE) == name) \ + if (cp_operator_id (CODE) == name) \ { \ operator_code = (CODE); \ break; \ } \ - else if (ansi_assopname (CODE) == name) \ + else if (cp_assignment_operator_id (CODE) == name) \ { \ operator_code = (CODE); \ DECL_ASSIGNMENT_OPERATOR_P (decl) = 1; \ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a9a1d2286a8..86d98202f0d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4386,7 +4386,7 @@ maybe_warn_sized_delete (enum tree_code code) tree sized = NULL_TREE; tree unsized = NULL_TREE; - for (tree ovl = IDENTIFIER_GLOBAL_VALUE (ansi_opname (code)); + for (tree ovl = IDENTIFIER_GLOBAL_VALUE (cp_operator_id (code)); ovl; ovl = OVL_NEXT (ovl)) { tree fn = OVL_CURRENT (ovl); diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 9eec9e48869..3815daef4d5 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -24,6 +24,46 @@ along with GCC; see the file COPYING3. If not see /* Friend data structures are described in cp-tree.h. */ + +/* The GLOBAL_FRIEND scope (functions, classes, or templates) is + regarded as a friend of every class. This is only used by libcc1, + to enable GDB's code snippets to access private members without + disabling access control in general, which could cause different + template overload resolution results when accessibility matters + (e.g. tests for an accessible member). */ + +static tree global_friend; + +/* Set the GLOBAL_FRIEND for this compilation session. It might be + set multiple times, but always to the same scope. */ + +void +set_global_friend (tree scope) +{ + gcc_checking_assert (scope != NULL_TREE); + gcc_assert (!global_friend || global_friend == scope); + global_friend = scope; +} + +/* Return TRUE if SCOPE is the global friend. */ + +bool +is_global_friend (tree scope) +{ + gcc_checking_assert (scope != NULL_TREE); + + if (global_friend == scope) + return true; + + if (!global_friend) + return false; + + if (is_specialization_of_friend (global_friend, scope)) + return true; + + return false; +} + /* Returns nonzero if SUPPLICANT is a friend of TYPE. */ int @@ -36,6 +76,9 @@ is_friend (tree type, tree supplicant) if (supplicant == NULL_TREE || type == NULL_TREE) return 0; + if (is_global_friend (supplicant)) + return 1; + declp = DECL_P (supplicant); if (declp) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index de43d81ce30..42f1c6192ec 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2924,7 +2924,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, tree fnname; tree fns; - fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR); + fnname = cp_operator_id (array_p ? VEC_NEW_EXPR : NEW_EXPR); member_new_p = !globally_qualified_p && CLASS_TYPE_P (elt_type) diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 4d22c3d37d9..538c8063957 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -202,7 +202,7 @@ lambda_function (tree lambda) if (CLASSTYPE_TEMPLATE_INSTANTIATION (type) && !COMPLETE_OR_OPEN_TYPE_P (type)) return NULL_TREE; - lambda = lookup_member (type, ansi_opname (CALL_EXPR), + lambda = lookup_member (type, cp_operator_id (CALL_EXPR), /*protect=*/0, /*want_type=*/false, tf_warning_or_error); if (lambda) diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 60a70e9b325..ad6318656ad 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -433,7 +433,7 @@ unqualified_name_lookup_error (tree name, location_t loc) if (IDENTIFIER_OPNAME_P (name)) { - if (name != ansi_opname (ERROR_MARK)) + if (name != cp_operator_id (ERROR_MARK)) error_at (loc, "%qD not defined", name); } else diff --git a/gcc/cp/method.c b/gcc/cp/method.c index e80b80606b5..941f9a657e4 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -812,7 +812,7 @@ do_build_copy_assign (tree fndecl) parmvec = make_tree_vector_single (converted_parm); finish_expr_stmt (build_special_member_call (current_class_ref, - ansi_assopname (NOP_EXPR), + cp_assignment_operator_id (NOP_EXPR), &parmvec, base_binfo, flags, @@ -1105,7 +1105,7 @@ get_copy_assign (tree type) int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type) ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); tree argtype = build_stub_type (type, quals, false); - tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype, + tree fn = locate_fn_flags (type, cp_assignment_operator_id (NOP_EXPR), argtype, LOOKUP_NORMAL, tf_warning_or_error); if (fn == error_mark_node) return NULL_TREE; @@ -1463,7 +1463,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, case sfk_move_assignment: case sfk_copy_assignment: assign_p = true; - fnname = ansi_assopname (NOP_EXPR); + fnname = cp_assignment_operator_id (NOP_EXPR); break; case sfk_destructor: @@ -1622,7 +1622,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, if (check_vdtor && type_has_virtual_destructor (basetype)) { - rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR), + rval = locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR), ptr_type_node, flags, complain); /* Unlike for base ctor/op=/dtor, for operator delete it's fine to have a null rval (no class-specific op delete). */ @@ -1949,7 +1949,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, || kind == sfk_move_assignment) { return_type = build_reference_type (type); - name = ansi_assopname (NOP_EXPR); + name = cp_assignment_operator_id (NOP_EXPR); } else name = constructor_name (type); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 10fb540e1f1..a3cb7eea907 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -92,6 +92,28 @@ get_anonymous_namespace_name (void) static GTY((deletable)) binding_entry free_binding_entry = NULL; +/* The binding oracle; see cp-tree.h. */ + +cp_binding_oracle_function *cp_binding_oracle; + +/* If we have a binding oracle, ask it for all namespace-scoped + definitions of NAME. */ + +static inline void +query_oracle (tree name) +{ + if (!cp_binding_oracle) + return; + + /* LOOKED_UP holds the set of identifiers that we have already + looked up with the oracle. */ + static hash_set<tree> looked_up; + if (looked_up.add (name)) + return; + + cp_binding_oracle (CP_ORACLE_IDENTIFIER, name); +} + /* Create a binding_entry object for (NAME, TYPE). */ static inline binding_entry @@ -4706,6 +4728,8 @@ qualified_lookup_using_namespace (tree name, tree scope, /* Look through namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); + query_oracle (name); + /* Algorithm: Starting with SCOPE, walk through the set of used namespaces. For each used namespace, look through its inline namespace set for any bindings and usings. If no bindings are @@ -5030,6 +5054,8 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, cxx_binding *iter; tree val = NULL_TREE; + query_oracle (name); + /* Conversion operators are handled specially because ordinary unqualified name lookup will not find template conversion operators. */ @@ -6238,6 +6264,7 @@ pushtag (tree name, tree type, tag_scope scope) timevar_cond_stop (TV_NAME_LOOKUP, subtime); return ret; } + /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7f685506bc1..592f903a6f9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -249,9 +249,6 @@ static cp_token_cache *cp_token_cache_new static void cp_parser_initial_pragma (cp_token *); -static tree cp_literal_operator_id - (const char *); - static void cp_parser_cilk_simd (cp_parser *, cp_token *, bool *); static tree cp_parser_cilk_for @@ -10279,7 +10276,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) p = obstack_alloc (&declarator_obstack, 0); - declarator = make_id_declarator (NULL_TREE, ansi_opname (CALL_EXPR), + declarator = make_id_declarator (NULL_TREE, cp_operator_id (CALL_EXPR), sfk_none); quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr) @@ -14297,7 +14294,7 @@ cp_parser_operator_function_id (cp_parser* parser) /* Return an identifier node for a user-defined literal operator. The suffix identifier is chained to the operator name identifier. */ -static tree +tree cp_literal_operator_id (const char* name) { tree identifier; @@ -14366,12 +14363,12 @@ cp_parser_operator (cp_parser* parser) if (cp_token *close_token = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)) end_loc = close_token->location; - id = ansi_opname (op == NEW_EXPR + id = cp_operator_id (op == NEW_EXPR ? VEC_NEW_EXPR : VEC_DELETE_EXPR); } /* Otherwise, we have the non-array variant. */ else - id = ansi_opname (op); + id = cp_operator_id (op); location_t loc = make_location (start_loc, start_loc, end_loc); @@ -14379,147 +14376,147 @@ cp_parser_operator (cp_parser* parser) } case CPP_PLUS: - id = ansi_opname (PLUS_EXPR); + id = cp_operator_id (PLUS_EXPR); break; case CPP_MINUS: - id = ansi_opname (MINUS_EXPR); + id = cp_operator_id (MINUS_EXPR); break; case CPP_MULT: - id = ansi_opname (MULT_EXPR); + id = cp_operator_id (MULT_EXPR); break; case CPP_DIV: - id = ansi_opname (TRUNC_DIV_EXPR); + id = cp_operator_id (TRUNC_DIV_EXPR); break; case CPP_MOD: - id = ansi_opname (TRUNC_MOD_EXPR); + id = cp_operator_id (TRUNC_MOD_EXPR); break; case CPP_XOR: - id = ansi_opname (BIT_XOR_EXPR); + id = cp_operator_id (BIT_XOR_EXPR); break; case CPP_AND: - id = ansi_opname (BIT_AND_EXPR); + id = cp_operator_id (BIT_AND_EXPR); break; case CPP_OR: - id = ansi_opname (BIT_IOR_EXPR); + id = cp_operator_id (BIT_IOR_EXPR); break; case CPP_COMPL: - id = ansi_opname (BIT_NOT_EXPR); + id = cp_operator_id (BIT_NOT_EXPR); break; case CPP_NOT: - id = ansi_opname (TRUTH_NOT_EXPR); + id = cp_operator_id (TRUTH_NOT_EXPR); break; case CPP_EQ: - id = ansi_assopname (NOP_EXPR); + id = cp_assignment_operator_id (NOP_EXPR); break; case CPP_LESS: - id = ansi_opname (LT_EXPR); + id = cp_operator_id (LT_EXPR); break; case CPP_GREATER: - id = ansi_opname (GT_EXPR); + id = cp_operator_id (GT_EXPR); break; case CPP_PLUS_EQ: - id = ansi_assopname (PLUS_EXPR); + id = cp_assignment_operator_id (PLUS_EXPR); break; case CPP_MINUS_EQ: - id = ansi_assopname (MINUS_EXPR); + id = cp_assignment_operator_id (MINUS_EXPR); break; case CPP_MULT_EQ: - id = ansi_assopname (MULT_EXPR); + id = cp_assignment_operator_id (MULT_EXPR); break; case CPP_DIV_EQ: - id = ansi_assopname (TRUNC_DIV_EXPR); + id = cp_assignment_operator_id (TRUNC_DIV_EXPR); break; case CPP_MOD_EQ: - id = ansi_assopname (TRUNC_MOD_EXPR); + id = cp_assignment_operator_id (TRUNC_MOD_EXPR); break; case CPP_XOR_EQ: - id = ansi_assopname (BIT_XOR_EXPR); + id = cp_assignment_operator_id (BIT_XOR_EXPR); break; case CPP_AND_EQ: - id = ansi_assopname (BIT_AND_EXPR); + id = cp_assignment_operator_id (BIT_AND_EXPR); break; case CPP_OR_EQ: - id = ansi_assopname (BIT_IOR_EXPR); + id = cp_assignment_operator_id (BIT_IOR_EXPR); break; case CPP_LSHIFT: - id = ansi_opname (LSHIFT_EXPR); + id = cp_operator_id (LSHIFT_EXPR); break; case CPP_RSHIFT: - id = ansi_opname (RSHIFT_EXPR); + id = cp_operator_id (RSHIFT_EXPR); break; case CPP_LSHIFT_EQ: - id = ansi_assopname (LSHIFT_EXPR); + id = cp_assignment_operator_id (LSHIFT_EXPR); break; case CPP_RSHIFT_EQ: - id = ansi_assopname (RSHIFT_EXPR); + id = cp_assignment_operator_id (RSHIFT_EXPR); break; case CPP_EQ_EQ: - id = ansi_opname (EQ_EXPR); + id = cp_operator_id (EQ_EXPR); break; case CPP_NOT_EQ: - id = ansi_opname (NE_EXPR); + id = cp_operator_id (NE_EXPR); break; case CPP_LESS_EQ: - id = ansi_opname (LE_EXPR); + id = cp_operator_id (LE_EXPR); break; case CPP_GREATER_EQ: - id = ansi_opname (GE_EXPR); + id = cp_operator_id (GE_EXPR); break; case CPP_AND_AND: - id = ansi_opname (TRUTH_ANDIF_EXPR); + id = cp_operator_id (TRUTH_ANDIF_EXPR); break; case CPP_OR_OR: - id = ansi_opname (TRUTH_ORIF_EXPR); + id = cp_operator_id (TRUTH_ORIF_EXPR); break; case CPP_PLUS_PLUS: - id = ansi_opname (POSTINCREMENT_EXPR); + id = cp_operator_id (POSTINCREMENT_EXPR); break; case CPP_MINUS_MINUS: - id = ansi_opname (PREDECREMENT_EXPR); + id = cp_operator_id (PREDECREMENT_EXPR); break; case CPP_COMMA: - id = ansi_opname (COMPOUND_EXPR); + id = cp_operator_id (COMPOUND_EXPR); break; case CPP_DEREF_STAR: - id = ansi_opname (MEMBER_REF); + id = cp_operator_id (MEMBER_REF); break; case CPP_DEREF: - id = ansi_opname (COMPONENT_REF); + id = cp_operator_id (COMPONENT_REF); break; case CPP_OPEN_PAREN: @@ -14527,14 +14524,14 @@ cp_parser_operator (cp_parser* parser) cp_lexer_consume_token (parser->lexer); /* Look for the matching `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); - return ansi_opname (CALL_EXPR); + return cp_operator_id (CALL_EXPR); case CPP_OPEN_SQUARE: /* Consume the `['. */ cp_lexer_consume_token (parser->lexer); /* Look for the matching `]'. */ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE); - return ansi_opname (ARRAY_REF); + return cp_operator_id (ARRAY_REF); case CPP_UTF8STRING: case CPP_UTF8STRING_USERDEF: @@ -31991,21 +31988,21 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list) code = MIN_EXPR; else if (strcmp (p, "max") == 0) code = MAX_EXPR; - else if (id == ansi_opname (PLUS_EXPR)) + else if (id == cp_operator_id (PLUS_EXPR)) code = PLUS_EXPR; - else if (id == ansi_opname (MULT_EXPR)) + else if (id == cp_operator_id (MULT_EXPR)) code = MULT_EXPR; - else if (id == ansi_opname (MINUS_EXPR)) + else if (id == cp_operator_id (MINUS_EXPR)) code = MINUS_EXPR; - else if (id == ansi_opname (BIT_AND_EXPR)) + else if (id == cp_operator_id (BIT_AND_EXPR)) code = BIT_AND_EXPR; - else if (id == ansi_opname (BIT_IOR_EXPR)) + else if (id == cp_operator_id (BIT_IOR_EXPR)) code = BIT_IOR_EXPR; - else if (id == ansi_opname (BIT_XOR_EXPR)) + else if (id == cp_operator_id (BIT_XOR_EXPR)) code = BIT_XOR_EXPR; - else if (id == ansi_opname (TRUTH_ANDIF_EXPR)) + else if (id == cp_operator_id (TRUTH_ANDIF_EXPR)) code = TRUTH_ANDIF_EXPR; - else if (id == ansi_opname (TRUTH_ORIF_EXPR)) + else if (id == cp_operator_id (TRUTH_ORIF_EXPR)) code = TRUTH_ORIF_EXPR; id = omp_reduction_id (code, id, NULL_TREE); tree scope = parser->scope; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index ec8f4ab4ba6..09c1b4e6456 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -782,6 +782,9 @@ friend_accessible_p (tree scope, tree decl, tree type, tree otype) if (!scope) return 0; + if (is_global_friend (scope)) + return 1; + /* Is SCOPE itself a suitable P? */ if (TYPE_P (scope) && protected_accessible_p (decl, scope, type, otype)) return 1; @@ -1664,7 +1667,7 @@ lookup_fnfields_1 (tree type, tree name) if (CLASSTYPE_LAZY_MOVE_CTOR (type)) lazily_declare_fn (sfk_move_constructor, type); } - else if (name == ansi_assopname (NOP_EXPR)) + else if (name == cp_assignment_operator_id (NOP_EXPR)) { if (CLASSTYPE_LAZY_COPY_ASSIGN (type)) lazily_declare_fn (sfk_copy_assignment, type); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 42b555c5883..bd91e1832f7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5107,7 +5107,7 @@ omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type) case BIT_IOR_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: - reduction_id = ansi_opname (reduction_code); + reduction_id = cp_operator_id (reduction_code); break; case MIN_EXPR: p = "min"; @@ -9012,7 +9012,7 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p) if (assign_p) { int ix; - ix = lookup_fnfields_1 (type, ansi_assopname (NOP_EXPR)); + ix = lookup_fnfields_1 (type, cp_assignment_operator_id (NOP_EXPR)); if (ix < 0) return false; fns = (*CLASSTYPE_METHOD_VEC (type))[ix]; @@ -9295,7 +9295,8 @@ is_this_parameter (tree t) { if (!DECL_P (t) || DECL_NAME (t) != this_identifier) return false; - gcc_assert (TREE_CODE (t) == PARM_DECL || is_capture_proxy (t)); + gcc_assert (TREE_CODE (t) == PARM_DECL || is_capture_proxy (t) + || (cp_binding_oracle && TREE_CODE (t) == VAR_DECL)); return true; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f677b48ee58..8f66d3c7933 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8881,7 +8881,7 @@ check_return_expr (tree retval, bool *no_warning) /* Effective C++ rule 15. See also start_function. */ if (warn_ecpp - && DECL_NAME (current_function_decl) == ansi_assopname(NOP_EXPR)) + && DECL_NAME (current_function_decl) == cp_assignment_operator_id (NOP_EXPR)) { bool warn = true; |