Make-lang.in (po-generated): Remove parse.c.
* Make-lang.in (po-generated): Remove parse.c. (CXX_OBJS): Remove parse.o and spew.o. Add parser.o. ($(srcdir)/cp/parse.h): Remove target. ($(srcdir)/cp/parse.c): Likewise. (gt-cp-parse.h): Likewise. (gt-cp-parser.h): New target. (c++.distclean): Do not remove parse.output. (c++.maintainer-clean): Do not remove parse.c or parse.h. (cp/spew.o): Remove target. (cp/lex.o): Adjust dependencies. (cp/pt.o): Likewise. (cp/parse.o): Likewise. (cp/TAGS): Do not mention parse.c. (cp/parser.o): New target. * NEWS: Mention the new parser. * call.c (build_scoped_method_call): Simplify. (build_method_call): Likewise. (build_new_function_call): Adjust calls to add_function_candidate and add_template_candidate. (build_new_op): Improve handling of erroroneous operands. (convert_default_arg): Remove circular argument processing. (name_as_c_string): New function. (build_new_method_call): Use it. (perform_implicit_conversion): Use error_operand_p. * class.c (finish_struct_anon): Use constructor_name_p. (check_field_decls): Likewise. (pop_nested_class): Use OVL_NEXT, not OVL_CHAIN. (resolve_address_of_overloaded_function): Likewise. (instantiate_type): Tweak pointer-to-member handling. (get_primary_binfo): Remove incorrect assertion. * config-lang.in (gtfiles): Add parser.c, remove parse.c. * cp-tree.h (DEFARG_TOKENS): New macro. (default_arg): New structure. (cp_tree_node_structure_enum): Add TS_CP_DEFAULT_ARG. (lang_tree_node): Add default_arg. (cp_tree_index): Add CPTI_TYPE_INFO_REF_TYPE. (type_info_ref_type): New macro. (saved_scope): Make processing_explicit_instantiation a boolean. (check_access): New field. (unparsed_text): Remove. (language_function): Remove unparsed_inlines. (error_operand_p): New macro. (lang_decl): Adjust pending_inline_info. (DEFARG_POINTER): Remove. (tag_types): Add typenames. (lookup_ualified_name): Declare. (lookup_name_real): Likewise. (shadow_tag): Adjust prototype. (get_scope_of_declarator): Declare it. (process_next_inline): Remove it. (check_for_missing_semicolon): Likewise. (maybe_get_template_decl_from_type_decl): Declare it. (finish_label_stmt): Adjust prototype. (finish_non_static_data_meber): Declare it. (finish_pseudo_destructor_call_expr): Rename to ... (finish_pseudo_destructor_expr): ... this. (finish_compound_literal): Declare it. (begin_inline_definitions): Remove it. (init_spew): Remove. (peekyylex): Likewise. (arbitrate_lookup): Likewise. (frob_opname): Likewise. (maybe_snarf_defarg): Likewise. (add_defarg_fn): Likewise. (do_pending_defargs): Likewise. (done_pending_defargs): Likewise. (unprocessed_defarg_fn): Likewise. (replace_defarg): Likewise. (end_input): Likewise. (get_overloaded_fn): Likewise. * cvt.c (convert_to_reference): Improve error handling. * decl.c (lookup_name_real): Do not declare it static. (maybe_push_to_top_level): Set check_access. (identifier_type_value): Adjust call to lookup_name_real. (lookup_qualified_name): New method. (lookup_name_real): Remove special-case parsing code. (lookup_name-nonclass): Adjust call to lookup_name_real. (lookup_name_namespace_only): Likewise. (lookup_name): Likewise. (check_tag_decl): Return the type declared. (shadow_tag): Likewise. (register_dtor_fn): Tweak check_access. (grokfndecl): Use constructor_name_p. (get_scope_of_declarator): New function. (grokdeclarator): Obscure tweaks for slightly different declarator representations. (start_method): Return error_mark_node to indicate failure. (cp_tree_node_structure_enum): Use TS_CP_DEFAULT_ARG for DEFAULT_ARGs. * decl2.c (constructor_name_full): Simplify. (constructor_name): Use it. (build_expr_from_tree): Adjust for changes to do new parser. (push_scope): Improve robustness. (validate_nonmember_using_decl): Process declarations, not names. (do_class_using_decl): Likewise. (handle_class_head): Do not mess with CLASSTYPE_DECLARED_CLASS here. * error.c (dump_expr): Handle IDENTIFIER_NODEs and BASELINKs. * expr.c (cxx_expand_expr): Handle BASELINKs. * init.c (member_init_ok_or_else): Issue more errors. (build_offset_ref): Tweak handling of FUNCTION_DECLs. * lex.c: Do not include parse.h. (yypring): Do not declare. (yylval): Likewise. (make_reference_declarator): Remove error-generating code. (rid_to_yy): Remove. (cxx_init): Do not call init_spew. (yypring): Remove. (check_for_missing_semicolon): Remove. * lex.h (got_scope): Remove. (got_object): Remove. * method.c (hack_identifier): Use finish_non_static_data_member. (implicitly_declare_fn): Adjust use of constructor_name. * parser.c: New file. * pt.c (parse.h): Do not include it. (maybe_get_template_decl_from_template): Do not declare it. (finish_member_template_decl): Tweak. (begin_explicit_instantiation): Adjust for processing_explicit_instantiation being boolean. (end_explicit_instantiation): Likewise. (maybe_process_partial_specialization): Tighten specialization test. (retrieve_local_specialization): Adjust ue of hash table. (eq_local_specializations): New function. (register_local_specialization): Likewise. (push_template_decl_real): Remove unnecessary test. (maybe_get_template_decl_from_type_decl): Don't make it static. (for_each_template_parm_r): Handle TYPEOF_TYPE. (tsubst_copy): Use retrieive_local_specialization to handle PARM_DECL. Adjust handling of CONST_DECLs. Handle BASELINKs. Handle COMPONENT_REFs with pseudo-destructor-expressions. Simplify handling of CALL_EXPR and METHOD_CALL_EXPR. (tsubst_expr): Pass decls, not names, to do_local_using_decl. (unify): Tweak handling of CONST_DECLs. (regenerate_decl_from_template): Use push_nested_class. (template_for_substitution): New funciton. (instantiate_decl): Use it. Register parameters as local specializations. * rtti.c (init_rtti_processing): Set type_info_ref_type. (build_typeid): Use it. (get_typeid): Likeise. * search.c (accessible_p): Use check_access, not flag_access_control. (adjust_result_of_qualified_name_lookup): Pay attention to the context_class. * semantics.c (finish_asm_stmt): Adjust error handling. (finish_label_stmt): Return the statement. (finish_non_static_data_member): New function. (finish_class_expr): Handle BASELINKs. (finish_call_expr): Handle PSEUDO_DTOR_EXPR. (finish_object_call_expr): Simplify handling during templates. (finish_pseudo_destructor_call_expr): Rename to ... (finish_pseudo_dtor_expr): ... this. (finish_compound_literal): New function. (begin_inline_definitions): Remove. (finish_sizeof): Remove special template handling. * spew.c: Do not include parse.h. * tree.c (get_overloaded_fn): Remove. * typeck.c (build_class_member_access_expr): Handle PSEUDO_DTOR_EXPR. Adjust handling of static member functions. (lookup_destructor): New function. (finish_class_member_access_expr): Use it. (convert_arguments): Simplify. (build_unary_op): Handle BASELINKs. From-SVN: r60560
This commit is contained in:
parent
876200a8b7
commit
a723baf1eb
166
gcc/cp/ChangeLog
166
gcc/cp/ChangeLog
@ -1,3 +1,169 @@
|
||||
2002-12-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* Make-lang.in (po-generated): Remove parse.c.
|
||||
(CXX_OBJS): Remove parse.o and spew.o. Add parser.o.
|
||||
($(srcdir)/cp/parse.h): Remove target.
|
||||
($(srcdir)/cp/parse.c): Likewise.
|
||||
(gt-cp-parse.h): Likewise.
|
||||
(gt-cp-parser.h): New target.
|
||||
(c++.distclean): Do not remove parse.output.
|
||||
(c++.maintainer-clean): Do not remove parse.c or parse.h.
|
||||
(cp/spew.o): Remove target.
|
||||
(cp/lex.o): Adjust dependencies.
|
||||
(cp/pt.o): Likewise.
|
||||
(cp/parse.o): Likewise.
|
||||
(cp/TAGS): Do not mention parse.c.
|
||||
(cp/parser.o): New target.
|
||||
* NEWS: Mention the new parser.
|
||||
* call.c (build_scoped_method_call): Simplify.
|
||||
(build_method_call): Likewise.
|
||||
(build_new_function_call): Adjust calls to add_function_candidate
|
||||
and add_template_candidate.
|
||||
(build_new_op): Improve handling of erroroneous operands.
|
||||
(convert_default_arg): Remove circular argument processing.
|
||||
(name_as_c_string): New function.
|
||||
(build_new_method_call): Use it.
|
||||
(perform_implicit_conversion): Use error_operand_p.
|
||||
* class.c (finish_struct_anon): Use constructor_name_p.
|
||||
(check_field_decls): Likewise.
|
||||
(pop_nested_class): Use OVL_NEXT, not OVL_CHAIN.
|
||||
(resolve_address_of_overloaded_function): Likewise.
|
||||
(instantiate_type): Tweak pointer-to-member handling.
|
||||
(get_primary_binfo): Remove incorrect assertion.
|
||||
* config-lang.in (gtfiles): Add parser.c, remove parse.c.
|
||||
* cp-tree.h (DEFARG_TOKENS): New macro.
|
||||
(default_arg): New structure.
|
||||
(cp_tree_node_structure_enum): Add TS_CP_DEFAULT_ARG.
|
||||
(lang_tree_node): Add default_arg.
|
||||
(cp_tree_index): Add CPTI_TYPE_INFO_REF_TYPE.
|
||||
(type_info_ref_type): New macro.
|
||||
(saved_scope): Make processing_explicit_instantiation a boolean.
|
||||
(check_access): New field.
|
||||
(unparsed_text): Remove.
|
||||
(language_function): Remove unparsed_inlines.
|
||||
(error_operand_p): New macro.
|
||||
(lang_decl): Adjust pending_inline_info.
|
||||
(DEFARG_POINTER): Remove.
|
||||
(tag_types): Add typenames.
|
||||
(lookup_ualified_name): Declare.
|
||||
(lookup_name_real): Likewise.
|
||||
(shadow_tag): Adjust prototype.
|
||||
(get_scope_of_declarator): Declare it.
|
||||
(process_next_inline): Remove it.
|
||||
(check_for_missing_semicolon): Likewise.
|
||||
(maybe_get_template_decl_from_type_decl): Declare it.
|
||||
(finish_label_stmt): Adjust prototype.
|
||||
(finish_non_static_data_meber): Declare it.
|
||||
(finish_pseudo_destructor_call_expr): Rename to ...
|
||||
(finish_pseudo_destructor_expr): ... this.
|
||||
(finish_compound_literal): Declare it.
|
||||
(begin_inline_definitions): Remove it.
|
||||
(init_spew): Remove.
|
||||
(peekyylex): Likewise.
|
||||
(arbitrate_lookup): Likewise.
|
||||
(frob_opname): Likewise.
|
||||
(maybe_snarf_defarg): Likewise.
|
||||
(add_defarg_fn): Likewise.
|
||||
(do_pending_defargs): Likewise.
|
||||
(done_pending_defargs): Likewise.
|
||||
(unprocessed_defarg_fn): Likewise.
|
||||
(replace_defarg): Likewise.
|
||||
(end_input): Likewise.
|
||||
(get_overloaded_fn): Likewise.
|
||||
* cvt.c (convert_to_reference): Improve error handling.
|
||||
* decl.c (lookup_name_real): Do not declare it static.
|
||||
(maybe_push_to_top_level): Set check_access.
|
||||
(identifier_type_value): Adjust call to lookup_name_real.
|
||||
(lookup_qualified_name): New method.
|
||||
(lookup_name_real): Remove special-case parsing code.
|
||||
(lookup_name-nonclass): Adjust call to lookup_name_real.
|
||||
(lookup_name_namespace_only): Likewise.
|
||||
(lookup_name): Likewise.
|
||||
(check_tag_decl): Return the type declared.
|
||||
(shadow_tag): Likewise.
|
||||
(register_dtor_fn): Tweak check_access.
|
||||
(grokfndecl): Use constructor_name_p.
|
||||
(get_scope_of_declarator): New function.
|
||||
(grokdeclarator): Obscure tweaks for slightly different declarator
|
||||
representations.
|
||||
(start_method): Return error_mark_node to indicate failure.
|
||||
(cp_tree_node_structure_enum): Use TS_CP_DEFAULT_ARG for DEFAULT_ARGs.
|
||||
* decl2.c (constructor_name_full): Simplify.
|
||||
(constructor_name): Use it.
|
||||
(build_expr_from_tree): Adjust for changes to do new parser.
|
||||
(push_scope): Improve robustness.
|
||||
(validate_nonmember_using_decl): Process declarations, not names.
|
||||
(do_class_using_decl): Likewise.
|
||||
(handle_class_head): Do not mess with CLASSTYPE_DECLARED_CLASS
|
||||
here.
|
||||
* error.c (dump_expr): Handle IDENTIFIER_NODEs and BASELINKs.
|
||||
* expr.c (cxx_expand_expr): Handle BASELINKs.
|
||||
* init.c (member_init_ok_or_else): Issue more errors.
|
||||
(build_offset_ref): Tweak handling of FUNCTION_DECLs.
|
||||
* lex.c: Do not include parse.h.
|
||||
(yypring): Do not declare.
|
||||
(yylval): Likewise.
|
||||
(make_reference_declarator): Remove error-generating code.
|
||||
(rid_to_yy): Remove.
|
||||
(cxx_init): Do not call init_spew.
|
||||
(yypring): Remove.
|
||||
(check_for_missing_semicolon): Remove.
|
||||
* lex.h (got_scope): Remove.
|
||||
(got_object): Remove.
|
||||
* method.c (hack_identifier): Use finish_non_static_data_member.
|
||||
(implicitly_declare_fn): Adjust use of constructor_name.
|
||||
* parser.c: New file.
|
||||
* pt.c (parse.h): Do not include it.
|
||||
(maybe_get_template_decl_from_template): Do not declare it.
|
||||
(finish_member_template_decl): Tweak.
|
||||
(begin_explicit_instantiation): Adjust for
|
||||
processing_explicit_instantiation being boolean.
|
||||
(end_explicit_instantiation): Likewise.
|
||||
(maybe_process_partial_specialization): Tighten specialization
|
||||
test.
|
||||
(retrieve_local_specialization): Adjust ue of hash table.
|
||||
(eq_local_specializations): New function.
|
||||
(register_local_specialization): Likewise.
|
||||
(push_template_decl_real): Remove unnecessary test.
|
||||
(maybe_get_template_decl_from_type_decl): Don't make it static.
|
||||
(for_each_template_parm_r): Handle TYPEOF_TYPE.
|
||||
(tsubst_copy): Use retrieive_local_specialization to handle
|
||||
PARM_DECL. Adjust handling of CONST_DECLs. Handle BASELINKs.
|
||||
Handle COMPONENT_REFs with pseudo-destructor-expressions.
|
||||
Simplify handling of CALL_EXPR and METHOD_CALL_EXPR.
|
||||
(tsubst_expr): Pass decls, not names, to do_local_using_decl.
|
||||
(unify): Tweak handling of CONST_DECLs.
|
||||
(regenerate_decl_from_template): Use push_nested_class.
|
||||
(template_for_substitution): New funciton.
|
||||
(instantiate_decl): Use it. Register parameters as local
|
||||
specializations.
|
||||
* rtti.c (init_rtti_processing): Set type_info_ref_type.
|
||||
(build_typeid): Use it.
|
||||
(get_typeid): Likeise.
|
||||
* search.c (accessible_p): Use check_access, not
|
||||
flag_access_control.
|
||||
(adjust_result_of_qualified_name_lookup): Pay attention to the
|
||||
context_class.
|
||||
* semantics.c (finish_asm_stmt): Adjust error handling.
|
||||
(finish_label_stmt): Return the statement.
|
||||
(finish_non_static_data_member): New function.
|
||||
(finish_class_expr): Handle BASELINKs.
|
||||
(finish_call_expr): Handle PSEUDO_DTOR_EXPR.
|
||||
(finish_object_call_expr): Simplify handling during templates.
|
||||
(finish_pseudo_destructor_call_expr): Rename to ...
|
||||
(finish_pseudo_dtor_expr): ... this.
|
||||
(finish_compound_literal): New function.
|
||||
(begin_inline_definitions): Remove.
|
||||
(finish_sizeof): Remove special template handling.
|
||||
* spew.c: Do not include parse.h.
|
||||
* tree.c (get_overloaded_fn): Remove.
|
||||
* typeck.c (build_class_member_access_expr): Handle
|
||||
PSEUDO_DTOR_EXPR. Adjust handling of static member functions.
|
||||
(lookup_destructor): New function.
|
||||
(finish_class_member_access_expr): Use it.
|
||||
(convert_arguments): Simplify.
|
||||
(build_unary_op): Handle BASELINKs.
|
||||
|
||||
2002-12-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/4803
|
||||
|
@ -63,7 +63,7 @@ g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CON
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
|
||||
$(INCLUDES) $(srcdir)/cp/g++spec.c)
|
||||
|
||||
po-generated: $(srcdir)/cp/parse.c
|
||||
po-generated:
|
||||
|
||||
# Create the compiler driver for g++.
|
||||
GXX_OBJS = gcc.o g++spec.o intl.o prefix.o version.o
|
||||
@ -83,8 +83,8 @@ CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
|
||||
|
||||
# Language-specific object files.
|
||||
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
|
||||
cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \
|
||||
cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
|
||||
cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o \
|
||||
cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
|
||||
cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o \
|
||||
cp/optimize.o cp/mangle.o cp/cp-lang.o
|
||||
|
||||
@ -101,21 +101,8 @@ $(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
|
||||
gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' \
|
||||
$(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h
|
||||
|
||||
$(srcdir)/cp/parse.h: $(srcdir)/cp/parse.c
|
||||
$(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y
|
||||
@echo "Expect 33 shift/reduce conflicts and 58 reduce/reduce conflicts."
|
||||
cd $(srcdir)/cp && \
|
||||
if $(BISON) $(BISONFLAGS) -d -o p$$$$.c parse.y; then \
|
||||
grep '^#define[ ]*YYEMPTY' p$$$$.c >> p$$$$.h ; \
|
||||
test -f p$$$$.output && mv -f p$$$$.output parse.output ; \
|
||||
mv -f p$$$$.c parse.c ; mv -f p$$$$.h parse.h ; \
|
||||
else \
|
||||
rm -f p$$$$.* ; \
|
||||
false ; \
|
||||
fi
|
||||
|
||||
gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true
|
||||
gt-cp-parse.h gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h : s-gtype; @true
|
||||
gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h gt-cp-parser.h : s-gtype; @true
|
||||
gt-cp-tree.h : s-gtype; @true
|
||||
|
||||
#
|
||||
@ -199,10 +186,8 @@ c++.mostlyclean:
|
||||
c++.clean:
|
||||
c++.distclean:
|
||||
-rm -f cp/config.status cp/Makefile
|
||||
-rm -f $(srcdir)/cp/parse.output
|
||||
c++.extraclean:
|
||||
c++.maintainer-clean:
|
||||
-rm -f $(srcdir)/cp/parse.c $(srcdir)/cp/parse.h
|
||||
#
|
||||
# Stage hooks:
|
||||
# The main makefile has already created stage?/cp.
|
||||
@ -222,9 +207,7 @@ CXX_TREE_H = $(TREE_H) cp/cp-tree.h c-common.h cp/cp-tree.def c-common.def \
|
||||
function.h varray.h $(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) \
|
||||
$(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
|
||||
|
||||
cp/spew.o: cp/spew.c $(CXX_TREE_H) $(TM_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \
|
||||
toplev.h gt-cp-spew.h
|
||||
cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \
|
||||
cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h \
|
||||
c-pragma.h toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h \
|
||||
cp/operators.def $(TM_P_H)
|
||||
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h langhooks.h \
|
||||
@ -257,7 +240,7 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.
|
||||
cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h
|
||||
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
|
||||
except.h $(TM_P_H)
|
||||
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h $(srcdir)/cp/parse.h cp/lex.h \
|
||||
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/lex.h \
|
||||
toplev.h $(GGC_H) $(RTL_H) except.h tree-inline.h gt-cp-pt.h
|
||||
cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h flags.h real.h \
|
||||
$(LANGHOOKS_DEF_H)
|
||||
@ -271,17 +254,13 @@ cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config
|
||||
input.h $(PARAMS_H) debug.h tree-inline.h
|
||||
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h
|
||||
|
||||
cp/parse.o: cp/parse.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h except.h output.h \
|
||||
cp/decl.h toplev.h $(GGC_H) gt-cp-parse.h
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
|
||||
$(srcdir)/cp/parse.c $(OUTPUT_OPTION)
|
||||
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h
|
||||
#
|
||||
# These exist for maintenance purposes.
|
||||
|
||||
# Update the tags table.
|
||||
cp/TAGS: force
|
||||
cd $(srcdir)/cp ; \
|
||||
etags --no-globals -l c `echo *.c | sed 's/parse.c//'` \
|
||||
parse.y *.h ../*.c ../*.h;
|
||||
etags --no-globals -l c *.c *.h ../*.c ../*.h;
|
||||
|
||||
.PHONY: cp/TAGS
|
||||
|
72
gcc/cp/NEWS
72
gcc/cp/NEWS
@ -1,3 +1,75 @@
|
||||
*** Changes in GCC 3.4:
|
||||
|
||||
* The C++ parser in G++ has been rewritten from scratch. As a result, G++
|
||||
is considerably more compliant to the C++ standard. As a result, it
|
||||
accepts more valid programs, and rejects more invalid programs.
|
||||
|
||||
Many of the changes below are a consequence of the new parser.
|
||||
|
||||
* Friend declarations that refer to template specializations are rejected
|
||||
if the template has not already been declared.
|
||||
|
||||
For example:
|
||||
|
||||
template <typename T>
|
||||
class C {
|
||||
friend void f<>(C&);
|
||||
};
|
||||
|
||||
is rejected; you must first declare `f' as a template:
|
||||
|
||||
template <typename T>
|
||||
void f(T);
|
||||
|
||||
* You must use "template <>" to introduce template specializations, as
|
||||
required by the standard. For example:
|
||||
|
||||
template <typename T>
|
||||
struct S;
|
||||
|
||||
struct S<int> { };
|
||||
|
||||
is rejected; you must write:
|
||||
|
||||
template <> struct S<int> {};
|
||||
|
||||
* You must now use the `typename' and `template' keywords to disambiguate
|
||||
dependent names, as required by the C++ standard.
|
||||
|
||||
* The "named return value" extension has been removed.
|
||||
|
||||
* The "implicit typename" extension has been removed.
|
||||
|
||||
* G++ used to accept code like this:
|
||||
|
||||
struct S {
|
||||
int h();
|
||||
void f(int i = g());
|
||||
int g(int i = h());
|
||||
};
|
||||
|
||||
This behavior is not mandated by the standard.
|
||||
|
||||
Now G++ issues an error about this code. To avoid the error, you must
|
||||
move the declaration of `g' before the declaration of `f'. The
|
||||
default arguments for `g' must be visible at the point where it is
|
||||
called.
|
||||
|
||||
* When -pedantic is used, G++ now issues errors about spurious semicolons;
|
||||
for example:
|
||||
|
||||
namespace N {}; // Invalid semicolon.
|
||||
void f() {}; // Invalid semicolon.
|
||||
|
||||
* G++ no longer accepts attributes for a declarator after the
|
||||
initializer associated with that declarator. For example:
|
||||
|
||||
X x(1) __attribute__((...));
|
||||
|
||||
is no longer accepted. Instead, use:
|
||||
|
||||
X x __attribute__((...)) (1);
|
||||
|
||||
*** Changes in GCC 3.3:
|
||||
|
||||
* The "new X = 3" extension has been removed; you must now use "new X(3)".
|
||||
|
231
gcc/cp/call.c
231
gcc/cp/call.c
@ -102,6 +102,7 @@ static tree convert_class_to_reference (tree, tree, tree);
|
||||
static tree direct_reference_binding (tree, tree);
|
||||
static bool promoted_arithmetic_type_p (tree);
|
||||
static tree conditional_conversion (tree, tree);
|
||||
static char *name_as_c_string (tree, tree, bool *);
|
||||
static tree call_builtin_trap (void);
|
||||
|
||||
tree
|
||||
@ -221,13 +222,6 @@ build_scoped_method_call (tree exp, tree basetype, tree name, tree parms)
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
|
||||
{
|
||||
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
|
||||
if (type)
|
||||
name = build_min_nt (BIT_NOT_EXPR, type);
|
||||
}
|
||||
name = build_min_nt (SCOPE_REF, basetype, name);
|
||||
return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE);
|
||||
}
|
||||
@ -477,24 +471,7 @@ build_method_call (tree instance, tree name, tree parms,
|
||||
return error_mark_node;
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
/* We need to process template parm names here so that tsubst catches
|
||||
them properly. Other type names can wait. */
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
tree type = NULL_TREE;
|
||||
|
||||
if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
|
||||
type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
|
||||
else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)
|
||||
type = TREE_TYPE (TREE_OPERAND (name, 0));
|
||||
|
||||
if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
|
||||
name = build_min_nt (BIT_NOT_EXPR, type);
|
||||
}
|
||||
|
||||
return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
|
||||
}
|
||||
return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
|
||||
|
||||
if (TREE_CODE (instance) == OFFSET_REF)
|
||||
instance = resolve_offset_ref (instance);
|
||||
@ -2685,8 +2662,8 @@ resolve_args (tree args)
|
||||
return args;
|
||||
}
|
||||
|
||||
/* Return an expression for a call to FN (a namespace-scope function)
|
||||
with the ARGS. */
|
||||
/* Return an expression for a call to FN (a namespace-scope function,
|
||||
or a static member function) with the ARGS. */
|
||||
|
||||
tree
|
||||
build_new_function_call (tree fn, tree args)
|
||||
@ -2726,18 +2703,21 @@ build_new_function_call (tree fn, tree args)
|
||||
{
|
||||
tree t = OVL_CURRENT (t1);
|
||||
|
||||
my_friendly_assert (!DECL_FUNCTION_MEMBER_P (t), 20020913);
|
||||
|
||||
if (TREE_CODE (t) == TEMPLATE_DECL)
|
||||
{
|
||||
templates = tree_cons (NULL_TREE, t, templates);
|
||||
candidates = add_template_candidate
|
||||
(candidates, t, NULL_TREE, explicit_targs, args,
|
||||
NULL_TREE,
|
||||
/*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
|
||||
NULL_TREE, /*access_path=*/NULL_TREE,
|
||||
/*conversion_path=*/NULL_TREE,
|
||||
LOOKUP_NORMAL, DEDUCE_CALL);
|
||||
}
|
||||
else if (! template_only)
|
||||
candidates = add_function_candidate
|
||||
(candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE,
|
||||
(candidates, t, NULL_TREE, args,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
|
||||
}
|
||||
|
||||
@ -3318,9 +3298,9 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3)
|
||||
tree conv;
|
||||
bool viable_candidates;
|
||||
|
||||
if (arg1 == error_mark_node
|
||||
|| arg2 == error_mark_node
|
||||
|| arg3 == error_mark_node)
|
||||
if (error_operand_p (arg1)
|
||||
|| error_operand_p (arg2)
|
||||
|| error_operand_p (arg3))
|
||||
return error_mark_node;
|
||||
|
||||
/* This can happen if a template takes all non-type parameters, e.g.
|
||||
@ -4186,24 +4166,14 @@ cxx_type_promotes_to (tree type)
|
||||
tree
|
||||
convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
||||
{
|
||||
/* If the ARG is an unparsed default argument expression, the
|
||||
conversion cannot be performed. */
|
||||
if (TREE_CODE (arg) == DEFAULT_ARG)
|
||||
{
|
||||
/* When processing the default args for a class, we can find that
|
||||
there is an ordering constraint, and we call a function who's
|
||||
default args have not yet been converted. For instance,
|
||||
class A {
|
||||
A (int = 0);
|
||||
void Foo (A const & = A ());
|
||||
};
|
||||
We must process A::A before A::Foo's default arg can be converted.
|
||||
Remember the dependent function, so do_pending_defargs can retry,
|
||||
and check loops. */
|
||||
unprocessed_defarg_fn (fn);
|
||||
|
||||
/* Don't return error_mark node, as we won't be able to distinguish
|
||||
genuine errors from this case, and that would lead to repeated
|
||||
diagnostics. Just make something of the right type. */
|
||||
return build1 (NOP_EXPR, type, integer_zero_node);
|
||||
error ("the default argument for parameter %d of `%D' has "
|
||||
"not yet been parsed",
|
||||
parmnum, fn);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (fn && DECL_TEMPLATE_INFO (fn))
|
||||
@ -4685,6 +4655,42 @@ build_special_member_call (tree instance, tree name, tree args,
|
||||
return build_new_method_call (instance, fns, args, binfo, flags);
|
||||
}
|
||||
|
||||
/* Return the NAME, as a C string. The NAME indicates a function that
|
||||
is a member of TYPE. *FREE_P is set to true if the caller must
|
||||
free the memory returned.
|
||||
|
||||
Rather than go through all of this, we should simply set the names
|
||||
of constructors and destructors appropriately, and dispense with
|
||||
ctor_identifier, dtor_identifier, etc. */
|
||||
|
||||
static char *
|
||||
name_as_c_string (tree name, tree type, bool *free_p)
|
||||
{
|
||||
char *pretty_name;
|
||||
|
||||
/* Assume that we will not allocate memory. */
|
||||
*free_p = false;
|
||||
/* Constructors and destructors are special. */
|
||||
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
|
||||
{
|
||||
pretty_name
|
||||
= (char *) IDENTIFIER_POINTER (constructor_name (type));
|
||||
/* For a destructor, add the '~'. */
|
||||
if (name == complete_dtor_identifier
|
||||
|| name == base_dtor_identifier
|
||||
|| name == deleting_dtor_identifier)
|
||||
{
|
||||
pretty_name = concat ("~", pretty_name, NULL);
|
||||
/* Remember that we need to free the memory allocated. */
|
||||
*free_p = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
pretty_name = (char *) IDENTIFIER_POINTER (name);
|
||||
|
||||
return pretty_name;
|
||||
}
|
||||
|
||||
/* Build a call to "INSTANCE.FN (ARGS)". */
|
||||
|
||||
tree
|
||||
@ -4697,15 +4703,18 @@ build_new_method_call (tree instance, tree fns, tree args,
|
||||
tree access_binfo;
|
||||
tree optype;
|
||||
tree mem_args = NULL_TREE, instance_ptr;
|
||||
tree name, pretty_name;
|
||||
tree name;
|
||||
tree user_args;
|
||||
tree templates = NULL_TREE;
|
||||
tree call;
|
||||
tree fn;
|
||||
tree class_type;
|
||||
int template_only = 0;
|
||||
|
||||
my_friendly_assert (instance != NULL_TREE, 20020729);
|
||||
|
||||
if (instance == error_mark_node || fns == error_mark_node
|
||||
if (error_operand_p (instance)
|
||||
|| error_operand_p (fns)
|
||||
|| args == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
@ -4759,7 +4768,8 @@ build_new_method_call (tree instance, tree fns, tree args,
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
name = DECL_NAME (get_first_fn (fns));
|
||||
fn = get_first_fn (fns);
|
||||
name = DECL_NAME (fn);
|
||||
|
||||
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
|
||||
{
|
||||
@ -4768,61 +4778,56 @@ build_new_method_call (tree instance, tree fns, tree args,
|
||||
my_friendly_assert (name != ctor_identifier, 20000408);
|
||||
/* Similarly for destructors. */
|
||||
my_friendly_assert (name != dtor_identifier, 20000408);
|
||||
|
||||
if (name == complete_ctor_identifier
|
||||
|| name == base_ctor_identifier)
|
||||
pretty_name = constructor_name (basetype);
|
||||
else
|
||||
pretty_name = dtor_identifier;
|
||||
}
|
||||
else
|
||||
pretty_name = name;
|
||||
|
||||
if (fns)
|
||||
/* It's OK to call destructors on cv-qualified objects. Therefore,
|
||||
convert the INSTANCE_PTR to the unqualified type, if necessary. */
|
||||
if (DECL_DESTRUCTOR_P (fn))
|
||||
{
|
||||
tree fn;
|
||||
tree class_type = (conversion_path
|
||||
? BINFO_TYPE (conversion_path)
|
||||
: NULL_TREE);
|
||||
tree type = build_pointer_type (basetype);
|
||||
if (!same_type_p (type, TREE_TYPE (instance_ptr)))
|
||||
instance_ptr = build1 (NOP_EXPR, type, instance_ptr);
|
||||
}
|
||||
|
||||
mem_args = tree_cons (NULL_TREE, instance_ptr, args);
|
||||
for (fn = fns; fn; fn = OVL_NEXT (fn))
|
||||
class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
|
||||
mem_args = tree_cons (NULL_TREE, instance_ptr, args);
|
||||
|
||||
for (fn = fns; fn; fn = OVL_NEXT (fn))
|
||||
{
|
||||
tree t = OVL_CURRENT (fn);
|
||||
tree this_arglist;
|
||||
|
||||
/* We can end up here for copy-init of same or base class. */
|
||||
if ((flags & LOOKUP_ONLYCONVERTING)
|
||||
&& DECL_NONCONVERTING_P (t))
|
||||
continue;
|
||||
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
|
||||
this_arglist = mem_args;
|
||||
else
|
||||
this_arglist = args;
|
||||
|
||||
if (TREE_CODE (t) == TEMPLATE_DECL)
|
||||
{
|
||||
tree t = OVL_CURRENT (fn);
|
||||
tree this_arglist;
|
||||
|
||||
/* We can end up here for copy-init of same or base class. */
|
||||
if ((flags & LOOKUP_ONLYCONVERTING)
|
||||
&& DECL_NONCONVERTING_P (t))
|
||||
continue;
|
||||
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
|
||||
this_arglist = mem_args;
|
||||
else
|
||||
this_arglist = args;
|
||||
|
||||
if (TREE_CODE (t) == TEMPLATE_DECL)
|
||||
{
|
||||
/* A member template. */
|
||||
templates = tree_cons (NULL_TREE, t, templates);
|
||||
candidates =
|
||||
add_template_candidate (candidates, t,
|
||||
class_type,
|
||||
explicit_targs,
|
||||
this_arglist, optype,
|
||||
access_binfo,
|
||||
conversion_path,
|
||||
flags,
|
||||
DEDUCE_CALL);
|
||||
}
|
||||
else if (! template_only)
|
||||
candidates = add_function_candidate (candidates, t,
|
||||
class_type,
|
||||
this_arglist,
|
||||
access_binfo,
|
||||
conversion_path,
|
||||
flags);
|
||||
/* A member template. */
|
||||
templates = tree_cons (NULL_TREE, t, templates);
|
||||
candidates =
|
||||
add_template_candidate (candidates, t,
|
||||
class_type,
|
||||
explicit_targs,
|
||||
this_arglist, optype,
|
||||
access_binfo,
|
||||
conversion_path,
|
||||
flags,
|
||||
DEDUCE_CALL);
|
||||
}
|
||||
else if (! template_only)
|
||||
candidates = add_function_candidate (candidates, t,
|
||||
class_type,
|
||||
this_arglist,
|
||||
access_binfo,
|
||||
conversion_path,
|
||||
flags);
|
||||
}
|
||||
|
||||
if (! any_viable (candidates))
|
||||
@ -4833,9 +4838,17 @@ build_new_method_call (tree instance, tree fns, tree args,
|
||||
if (!COMPLETE_TYPE_P (basetype))
|
||||
cxx_incomplete_type_error (instance_ptr, basetype);
|
||||
else
|
||||
error ("no matching function for call to `%T::%D(%A)%#V'",
|
||||
basetype, pretty_name, user_args,
|
||||
TREE_TYPE (TREE_TYPE (instance_ptr)));
|
||||
{
|
||||
char *pretty_name;
|
||||
bool free_p;
|
||||
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("no matching function for call to `%T::%s(%A)%#V'",
|
||||
basetype, pretty_name, user_args,
|
||||
TREE_TYPE (TREE_TYPE (instance_ptr)));
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
}
|
||||
print_z_candidates (candidates);
|
||||
return error_mark_node;
|
||||
}
|
||||
@ -4844,9 +4857,15 @@ build_new_method_call (tree instance, tree fns, tree args,
|
||||
|
||||
if (cand == 0)
|
||||
{
|
||||
char *pretty_name;
|
||||
bool free_p;
|
||||
|
||||
pretty_name = name_as_c_string (name, basetype, &free_p);
|
||||
error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
|
||||
user_args);
|
||||
user_args);
|
||||
print_z_candidates (candidates);
|
||||
if (free_p)
|
||||
free (pretty_name);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
@ -5745,7 +5764,7 @@ perform_implicit_conversion (tree type, tree expr)
|
||||
{
|
||||
tree conv;
|
||||
|
||||
if (expr == error_mark_node)
|
||||
if (error_operand_p (expr))
|
||||
return error_mark_node;
|
||||
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
|
||||
LOOKUP_NORMAL);
|
||||
|
@ -2739,7 +2739,7 @@ finish_struct_anon (t)
|
||||
|| TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
|
||||
continue;
|
||||
|
||||
if (DECL_NAME (elt) == constructor_name (t))
|
||||
if (constructor_name_p (DECL_NAME (elt), t))
|
||||
cp_pedwarn_at ("ISO C++ forbids member `%D' with same name as enclosing class",
|
||||
elt);
|
||||
|
||||
@ -3341,8 +3341,7 @@ check_field_decls (tree t, tree *access_decls,
|
||||
/* Core issue 80: A nonstatic data member is required to have a
|
||||
different name from the class iff the class has a
|
||||
user-defined constructor. */
|
||||
if (DECL_NAME (x) == constructor_name (t)
|
||||
&& TYPE_HAS_CONSTRUCTOR (t))
|
||||
if (constructor_name_p (x, t) && TYPE_HAS_CONSTRUCTOR (t))
|
||||
cp_pedwarn_at ("field `%#D' with same name as class", x);
|
||||
|
||||
/* We set DECL_C_BIT_FIELD in grokbitfield.
|
||||
@ -5642,15 +5641,8 @@ init_class_processing ()
|
||||
ridpointers[(int) RID_PROTECTED] = access_protected_node;
|
||||
}
|
||||
|
||||
/* Set current scope to NAME. CODE tells us if this is a
|
||||
STRUCT, UNION, or ENUM environment.
|
||||
|
||||
NAME may end up being NULL_TREE if this is an anonymous or
|
||||
late-bound struct (as in "struct { ... } foo;") */
|
||||
|
||||
/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to
|
||||
appropriate values, found by looking up the type definition of
|
||||
NAME (as a CODE).
|
||||
/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE as
|
||||
appropriate for TYPE.
|
||||
|
||||
If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names
|
||||
which can be seen locally to the class. They are shadowed by
|
||||
@ -5860,7 +5852,7 @@ push_nested_class (type, modify)
|
||||
pushclass (type, modify);
|
||||
}
|
||||
|
||||
/* Undoes a push_nested_class call. MODIFY is passed on to popclass. */
|
||||
/* Undoes a push_nested_class call. */
|
||||
|
||||
void
|
||||
pop_nested_class ()
|
||||
@ -6024,9 +6016,9 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
|
||||
{
|
||||
tree fns;
|
||||
|
||||
for (fns = overload; fns; fns = OVL_CHAIN (fns))
|
||||
for (fns = overload; fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree fn = OVL_FUNCTION (fns);
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
tree fntype;
|
||||
|
||||
if (TREE_CODE (fn) == TEMPLATE_DECL)
|
||||
@ -6073,9 +6065,9 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
|
||||
if (TREE_CODE (target_fn_type) == METHOD_TYPE)
|
||||
target_arg_types = TREE_CHAIN (target_arg_types);
|
||||
|
||||
for (fns = overload; fns; fns = OVL_CHAIN (fns))
|
||||
for (fns = overload; fns; fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree fn = OVL_FUNCTION (fns);
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
tree instantiation;
|
||||
tree instantiation_type;
|
||||
tree targs;
|
||||
@ -6235,10 +6227,19 @@ instantiate_type (lhstype, rhs, flags)
|
||||
{
|
||||
if (comptypes (lhstype, TREE_TYPE (rhs), strict))
|
||||
return rhs;
|
||||
if (complain)
|
||||
error ("argument of type `%T' does not match `%T'",
|
||||
TREE_TYPE (rhs), lhstype);
|
||||
return error_mark_node;
|
||||
if (flag_ms_extensions
|
||||
&& TYPE_PTRMEMFUNC_P (lhstype)
|
||||
&& !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
|
||||
/* Microsoft allows `A::f' to be resolved to a
|
||||
pointer-to-member. */
|
||||
;
|
||||
else
|
||||
{
|
||||
if (complain)
|
||||
error ("argument of type `%T' does not match `%T'",
|
||||
TREE_TYPE (rhs), lhstype);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (rhs) == BASELINK)
|
||||
@ -6314,6 +6315,7 @@ instantiate_type (lhstype, rhs, flags)
|
||||
}
|
||||
|
||||
case OVERLOAD:
|
||||
case FUNCTION_DECL:
|
||||
return
|
||||
resolve_address_of_overloaded_function (lhstype,
|
||||
rhs,
|
||||
@ -6771,10 +6773,8 @@ get_primary_binfo (binfo)
|
||||
|
||||
if (TREE_CHAIN (virtuals))
|
||||
{
|
||||
/* We found more than one instance of the base. We must make
|
||||
sure that, if one is the canonical one, it is the first one
|
||||
we found. As the chain is in reverse dfs order, that means
|
||||
the last on the list. */
|
||||
/* We found more than one instance of the base. If one is the
|
||||
canonical one, choose that one. */
|
||||
tree complete_binfo;
|
||||
tree canonical;
|
||||
|
||||
@ -6790,12 +6790,7 @@ get_primary_binfo (binfo)
|
||||
result = TREE_VALUE (virtuals);
|
||||
|
||||
if (canonical == result)
|
||||
{
|
||||
/* This is the unshared instance. Make sure it was the
|
||||
first one found. */
|
||||
my_friendly_assert (!TREE_CHAIN (virtuals), 20010612);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
|
||||
|
||||
target_libs="${libstdcxx_version} target-gperf"
|
||||
|
||||
gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c \$(srcdir)/cp/tree.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
|
||||
gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
|
||||
|
@ -501,6 +501,17 @@ struct tree_srcloc GTY(())
|
||||
#define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
|
||||
(TREE_COMPLEXITY (EXP) = (int)(CODE))
|
||||
|
||||
/* The tokens stored in the default argument. */
|
||||
|
||||
#define DEFARG_TOKENS(NODE) \
|
||||
(((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->tokens)
|
||||
|
||||
struct tree_default_arg GTY (())
|
||||
{
|
||||
struct tree_common common;
|
||||
struct cp_token_cache *tokens;
|
||||
};
|
||||
|
||||
enum cp_tree_node_structure_enum {
|
||||
TS_CP_COMMON,
|
||||
TS_CP_GENERIC,
|
||||
@ -511,6 +522,7 @@ enum cp_tree_node_structure_enum {
|
||||
TS_CP_OVERLOAD,
|
||||
TS_CP_WRAPPER,
|
||||
TS_CP_SRCLOC,
|
||||
TS_CP_DEFAULT_ARG,
|
||||
LAST_TS_CP_ENUM
|
||||
};
|
||||
|
||||
@ -527,6 +539,7 @@ union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
|
||||
struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
|
||||
struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper;
|
||||
struct tree_srcloc GTY ((tag ("TS_CP_SRCLOC"))) srcloc;
|
||||
struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg;
|
||||
struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier;
|
||||
};
|
||||
|
||||
@ -572,6 +585,7 @@ enum cp_tree_index
|
||||
CPTI_ABI,
|
||||
CPTI_TYPE_INFO_TYPE,
|
||||
CPTI_TYPE_INFO_PTR_TYPE,
|
||||
CPTI_TYPE_INFO_REF_TYPE,
|
||||
CPTI_ABORT_FNDECL,
|
||||
CPTI_GLOBAL_DELETE_FNDECL,
|
||||
CPTI_AGGR_TAG,
|
||||
@ -661,6 +675,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
|
||||
#define abi_node cp_global_trees[CPTI_ABI]
|
||||
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
|
||||
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
|
||||
#define type_info_ref_type cp_global_trees[CPTI_TYPE_INFO_REF_TYPE]
|
||||
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
|
||||
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
|
||||
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
|
||||
@ -772,8 +787,9 @@ struct saved_scope GTY(())
|
||||
|
||||
HOST_WIDE_INT x_processing_template_decl;
|
||||
int x_processing_specialization;
|
||||
int x_processing_explicit_instantiation;
|
||||
bool x_processing_explicit_instantiation;
|
||||
int need_pop_function_context;
|
||||
int check_access;
|
||||
|
||||
struct stmt_tree_s x_stmt_tree;
|
||||
|
||||
@ -837,8 +853,6 @@ struct saved_scope GTY(())
|
||||
|
||||
extern GTY(()) struct saved_scope *scope_chain;
|
||||
|
||||
struct unparsed_text;
|
||||
|
||||
/* Global state pertinent to the current function. */
|
||||
|
||||
struct language_function GTY(())
|
||||
@ -865,7 +879,6 @@ struct language_function GTY(())
|
||||
varray_type x_local_names;
|
||||
|
||||
const char *cannot_inline;
|
||||
struct unparsed_text *unparsed_inlines;
|
||||
};
|
||||
|
||||
/* The current C++-specific per-function global variables. */
|
||||
@ -943,6 +956,12 @@ extern GTY(()) tree global_namespace;
|
||||
#define ansi_assopname(CODE) \
|
||||
(assignment_operator_name_info[(int) (CODE)].identifier)
|
||||
|
||||
/* True if NODE is an erroneous expression. */
|
||||
|
||||
#define error_operand_p(NODE) \
|
||||
((NODE) == error_mark_node \
|
||||
|| ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
|
||||
|
||||
/* INTERFACE_ONLY nonzero means that we are in an "interface"
|
||||
section of the compiler. INTERFACE_UNKNOWN nonzero means
|
||||
we cannot trust the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN
|
||||
@ -1799,7 +1818,7 @@ struct lang_decl GTY(())
|
||||
union lang_decl_u3
|
||||
{
|
||||
tree GTY ((tag ("0"))) sorted_fields;
|
||||
struct unparsed_text * GTY ((tag ("2"))) pending_inline_info;
|
||||
struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;
|
||||
struct language_function * GTY ((tag ("1")))
|
||||
saved_language_function;
|
||||
} GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;
|
||||
@ -1822,8 +1841,6 @@ struct lang_decl GTY(())
|
||||
|
||||
#endif /* ENABLE_TREE_CHECKING */
|
||||
|
||||
#define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK (NODE)->identifier.id.str)
|
||||
|
||||
/* DECL_NEEDED_P holds of a declaration when we need to emit its
|
||||
definition. This is true when the back-end tells us that
|
||||
the symbol has been referenced in the generated code. If, however,
|
||||
@ -2998,7 +3015,14 @@ struct lang_decl GTY(())
|
||||
(TREE_TYPE (NODE))
|
||||
|
||||
/* An enumeration of the kind of tags that C++ accepts. */
|
||||
enum tag_types { record_type, class_type, union_type, enum_type };
|
||||
enum tag_types {
|
||||
none_type = 0, /* Not a tag type. */
|
||||
record_type, /* "struct" types. */
|
||||
class_type, /* "class" types. */
|
||||
union_type, /* "union" types. */
|
||||
enum_type, /* "enum" types. */
|
||||
typename_type /* "typename" types. */
|
||||
};
|
||||
|
||||
/* The various kinds of lvalues we distinguish. */
|
||||
typedef enum cp_lvalue_kind {
|
||||
@ -3703,10 +3727,12 @@ extern tree make_typename_type PARAMS ((tree, tree, tsubst_flags_t));
|
||||
extern tree make_unbound_class_template PARAMS ((tree, tree, tsubst_flags_t));
|
||||
extern tree lookup_name_nonclass PARAMS ((tree));
|
||||
extern tree lookup_function_nonclass PARAMS ((tree, tree));
|
||||
extern tree lookup_qualified_name (tree, tree, bool, int);
|
||||
extern tree lookup_name PARAMS ((tree, int));
|
||||
extern tree lookup_name_current_level PARAMS ((tree));
|
||||
extern tree lookup_type_current_level PARAMS ((tree));
|
||||
extern tree lookup_name_namespace_only PARAMS ((tree));
|
||||
extern tree lookup_name_real (tree, int, int, int, int);
|
||||
extern void begin_only_namespace_names PARAMS ((void));
|
||||
extern void end_only_namespace_names PARAMS ((void));
|
||||
extern tree namespace_ancestor PARAMS ((tree, tree));
|
||||
@ -3722,7 +3748,7 @@ extern tree push_void_library_fn PARAMS ((tree, tree));
|
||||
extern tree push_throw_library_fn PARAMS ((tree, tree));
|
||||
extern int init_type_desc PARAMS ((void));
|
||||
extern tree check_tag_decl PARAMS ((tree));
|
||||
extern void shadow_tag PARAMS ((tree));
|
||||
extern tree shadow_tag PARAMS ((tree));
|
||||
extern tree groktypename PARAMS ((tree));
|
||||
extern tree start_decl PARAMS ((tree, tree, int, tree, tree));
|
||||
extern void start_decl_1 PARAMS ((tree));
|
||||
@ -3736,6 +3762,7 @@ extern tree build_ptrmem_type (tree, tree);
|
||||
/* the grokdeclarator prototype is in decl.h */
|
||||
extern int parmlist_is_exprlist PARAMS ((tree));
|
||||
extern int copy_fn_p PARAMS ((tree));
|
||||
extern tree get_scope_of_declarator PARAMS ((tree));
|
||||
extern void grok_special_member_properties PARAMS ((tree));
|
||||
extern int grok_ctor_properties PARAMS ((tree, tree));
|
||||
extern void grok_op_properties PARAMS ((tree, int));
|
||||
@ -3937,12 +3964,9 @@ extern tree make_call_declarator PARAMS ((tree, tree, tree, tree));
|
||||
extern void set_quals_and_spec PARAMS ((tree, tree, tree));
|
||||
extern void print_parse_statistics PARAMS ((void));
|
||||
extern void do_pending_inlines PARAMS ((void));
|
||||
extern void process_next_inline PARAMS ((struct unparsed_text *));
|
||||
|
||||
extern void yyungetc PARAMS ((int, int));
|
||||
extern void snarf_method PARAMS ((tree));
|
||||
|
||||
extern void check_for_missing_semicolon PARAMS ((tree));
|
||||
extern void note_got_semicolon PARAMS ((tree));
|
||||
extern void note_list_got_semicolon PARAMS ((tree));
|
||||
extern void do_pending_lang_change PARAMS ((void));
|
||||
@ -4037,6 +4061,7 @@ extern tree get_mostly_instantiated_function_type PARAMS ((tree));
|
||||
extern int problematic_instantiation_changed PARAMS ((void));
|
||||
extern void record_last_problematic_instantiation PARAMS ((void));
|
||||
extern tree current_instantiation PARAMS ((void));
|
||||
extern tree maybe_get_template_decl_from_type_decl (tree);
|
||||
extern int processing_template_parmlist;
|
||||
|
||||
/* in repo.c */
|
||||
@ -4154,10 +4179,11 @@ extern void finish_cleanup PARAMS ((tree, tree));
|
||||
extern tree begin_compound_stmt PARAMS ((int));
|
||||
extern tree finish_compound_stmt PARAMS ((int, tree));
|
||||
extern tree finish_asm_stmt PARAMS ((tree, tree, tree, tree, tree));
|
||||
extern void finish_label_stmt PARAMS ((tree));
|
||||
extern tree finish_label_stmt PARAMS ((tree));
|
||||
extern void finish_label_decl PARAMS ((tree));
|
||||
extern void finish_subobject PARAMS ((tree));
|
||||
extern tree finish_parenthesized_expr PARAMS ((tree));
|
||||
extern tree finish_non_static_data_member PARAMS ((tree, tree));
|
||||
extern tree begin_stmt_expr PARAMS ((void));
|
||||
extern tree finish_stmt_expr PARAMS ((tree));
|
||||
extern tree finish_call_expr (tree, tree, bool);
|
||||
@ -4165,9 +4191,10 @@ extern tree finish_increment_expr PARAMS ((tree, enum tree_code));
|
||||
extern tree finish_this_expr PARAMS ((void));
|
||||
extern tree finish_object_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree));
|
||||
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
|
||||
extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
|
||||
extern tree finish_id_expr PARAMS ((tree));
|
||||
extern tree finish_compound_literal (tree, tree);
|
||||
extern tree finish_fname (tree);
|
||||
extern void save_type_access_control PARAMS ((tree));
|
||||
extern void reset_type_access_control PARAMS ((void));
|
||||
@ -4182,7 +4209,6 @@ extern tree finish_parmlist PARAMS ((tree, int));
|
||||
extern tree begin_class_definition PARAMS ((tree));
|
||||
extern tree finish_class_definition PARAMS ((tree, tree, int, int));
|
||||
extern void finish_default_args PARAMS ((void));
|
||||
extern void begin_inline_definitions PARAMS ((void));
|
||||
extern tree finish_member_class_template PARAMS ((tree));
|
||||
extern void finish_template_decl PARAMS ((tree));
|
||||
extern tree finish_template_type PARAMS ((tree, tree, int));
|
||||
@ -4208,19 +4234,6 @@ extern tree begin_global_stmt_expr PARAMS ((void));
|
||||
extern tree finish_global_stmt_expr PARAMS ((tree));
|
||||
extern tree check_template_template_default_arg (tree);
|
||||
|
||||
/* in spew.c */
|
||||
extern void init_spew PARAMS ((void));
|
||||
extern int peekyylex PARAMS ((void));
|
||||
extern tree arbitrate_lookup PARAMS ((tree, tree, tree));
|
||||
extern tree frob_opname PARAMS ((tree));
|
||||
extern void maybe_snarf_defarg PARAMS ((void));
|
||||
extern void add_defarg_fn PARAMS ((tree));
|
||||
extern void do_pending_defargs PARAMS ((void));
|
||||
extern void done_pending_defargs PARAMS ((void));
|
||||
extern void unprocessed_defarg_fn PARAMS ((tree));
|
||||
extern void replace_defarg PARAMS ((tree, tree));
|
||||
extern void end_input PARAMS ((void));
|
||||
|
||||
/* in tree.c */
|
||||
extern void lang_check_failed PARAMS ((const char *, int,
|
||||
const char *));
|
||||
@ -4252,7 +4265,6 @@ extern tree make_binfo PARAMS ((tree, tree, tree, tree));
|
||||
extern tree reverse_path PARAMS ((tree));
|
||||
extern int count_functions PARAMS ((tree));
|
||||
extern int is_overloaded_fn PARAMS ((tree));
|
||||
extern tree get_overloaded_fn PARAMS ((tree));
|
||||
extern tree get_first_fn PARAMS ((tree));
|
||||
extern int bound_pmf_p PARAMS ((tree));
|
||||
extern tree ovl_cons PARAMS ((tree, tree));
|
||||
|
22
gcc/cp/cvt.c
22
gcc/cp/cvt.c
@ -484,20 +484,16 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
||||
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE
|
||||
&& TREE_TYPE (expr) == unknown_type_node)
|
||||
{
|
||||
expr = instantiate_type (type, expr,
|
||||
(flags & LOOKUP_COMPLAIN)
|
||||
? tf_error | tf_warning : tf_none);
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
intype = TREE_TYPE (expr);
|
||||
}
|
||||
expr = instantiate_type (type, expr,
|
||||
(flags & LOOKUP_COMPLAIN)
|
||||
? tf_error | tf_warning : tf_none);
|
||||
else
|
||||
{
|
||||
expr = convert_from_reference (expr);
|
||||
intype = TREE_TYPE (expr);
|
||||
}
|
||||
expr = convert_from_reference (expr);
|
||||
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
intype = TREE_TYPE (expr);
|
||||
|
||||
my_friendly_assert (TREE_CODE (intype) != REFERENCE_TYPE, 364);
|
||||
|
||||
|
494
gcc/cp/decl.c
494
gcc/cp/decl.c
@ -69,7 +69,6 @@ static int ambi_op_p PARAMS ((enum tree_code));
|
||||
static int unary_op_p PARAMS ((enum tree_code));
|
||||
static tree store_bindings PARAMS ((tree, tree));
|
||||
static tree lookup_tag_reverse PARAMS ((tree, tree));
|
||||
static tree lookup_name_real PARAMS ((tree, int, int, int));
|
||||
static void push_local_name PARAMS ((tree));
|
||||
static void warn_extern_redeclared_static PARAMS ((tree, tree));
|
||||
static tree grok_reference_init PARAMS ((tree, tree, tree));
|
||||
@ -2428,6 +2427,7 @@ maybe_push_to_top_level (pseudo)
|
||||
s->need_pop_function_context = need_pop;
|
||||
s->function_decl = current_function_decl;
|
||||
s->last_parms = last_function_parms;
|
||||
s->check_access = flag_access_control;
|
||||
|
||||
scope_chain = s;
|
||||
current_function_decl = NULL_TREE;
|
||||
@ -2532,8 +2532,8 @@ identifier_type_value (id)
|
||||
if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
|
||||
return REAL_IDENTIFIER_TYPE_VALUE (id);
|
||||
/* Have to search for it. It must be on the global level, now.
|
||||
Ask lookup_name not to return non-types. */
|
||||
id = lookup_name_real (id, 2, 1, 0);
|
||||
Ask lookup_name not to return non-types. */
|
||||
id = lookup_name_real (id, 2, 1, 0, LOOKUP_COMPLAIN);
|
||||
if (id)
|
||||
return TREE_TYPE (id);
|
||||
return NULL_TREE;
|
||||
@ -5980,6 +5980,32 @@ warn_about_implicit_typename_lookup (typename, binding)
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
|
||||
or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type
|
||||
bindings.
|
||||
|
||||
Returns a DECL (or OVERLOAD, or BASELINK) representing the
|
||||
declaration found. */
|
||||
|
||||
tree
|
||||
lookup_qualified_name (tree scope, tree name, bool is_type_p, int flags)
|
||||
{
|
||||
if (TREE_CODE (scope) == NAMESPACE_DECL)
|
||||
{
|
||||
tree val;
|
||||
|
||||
val = make_node (CPLUS_BINDING);
|
||||
flags |= LOOKUP_COMPLAIN;
|
||||
if (is_type_p)
|
||||
flags |= LOOKUP_PREFER_TYPES;
|
||||
if (!qualified_lookup_using_namespace (name, scope, val, flags))
|
||||
return NULL_TREE;
|
||||
return select_decl (val, flags);
|
||||
}
|
||||
else
|
||||
return lookup_member (scope, name, 0, is_type_p);
|
||||
}
|
||||
|
||||
/* Check to see whether or not DECL is a variable that would have been
|
||||
in scope under the ARM, but is not in scope under the ANSI/ISO
|
||||
standard. If so, issue an error message. If name lookup would
|
||||
@ -6047,111 +6073,57 @@ check_for_out_of_scope_variable (tree decl)
|
||||
|
||||
If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
|
||||
If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
|
||||
If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
|
||||
Otherwise we prefer non-TYPE_DECLs.
|
||||
|
||||
If NONCLASS is nonzero, we don't look for the NAME in class scope,
|
||||
using IDENTIFIER_CLASS_VALUE. */
|
||||
|
||||
static tree
|
||||
lookup_name_real (name, prefer_type, nonclass, namespaces_only)
|
||||
tree name;
|
||||
int prefer_type, nonclass, namespaces_only;
|
||||
tree
|
||||
lookup_name_real (tree name,
|
||||
int prefer_type,
|
||||
int nonclass,
|
||||
int namespaces_only,
|
||||
int flags)
|
||||
{
|
||||
tree t;
|
||||
tree val = NULL_TREE;
|
||||
int yylex = 0;
|
||||
tree from_obj = NULL_TREE;
|
||||
int flags;
|
||||
int val_is_implicit_typename = 0;
|
||||
|
||||
/* Hack: copy flag set by parser, if set. */
|
||||
/* Conversion operators are handled specially because ordinary
|
||||
unqualified name lookup will not find template conversion
|
||||
operators. */
|
||||
if (IDENTIFIER_TYPENAME_P (name))
|
||||
{
|
||||
struct cp_binding_level *level;
|
||||
|
||||
for (level = current_binding_level;
|
||||
level && !level->namespace_p;
|
||||
level = level->level_chain)
|
||||
{
|
||||
tree class_type;
|
||||
tree operators;
|
||||
|
||||
/* A conversion operator can only be declared in a class
|
||||
scope. */
|
||||
if (level->parm_flag != 2)
|
||||
continue;
|
||||
|
||||
/* Lookup the conversion operator in the class. */
|
||||
class_type = level->this_class;
|
||||
operators = lookup_fnfields (class_type, name, /*protect=*/0);
|
||||
if (operators)
|
||||
return operators;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Hack: copy flag set by parser, if set. */
|
||||
if (only_namespace_names)
|
||||
namespaces_only = 1;
|
||||
|
||||
if (prefer_type == -2)
|
||||
{
|
||||
extern int looking_for_typename;
|
||||
tree type = NULL_TREE;
|
||||
|
||||
yylex = 1;
|
||||
prefer_type = looking_for_typename;
|
||||
|
||||
flags = lookup_flags (prefer_type, namespaces_only);
|
||||
/* If the next thing is '<', class templates are types. */
|
||||
if (looking_for_template)
|
||||
flags |= LOOKUP_TEMPLATES_EXPECTED;
|
||||
|
||||
if (got_scope)
|
||||
type = got_scope;
|
||||
else if (got_object != error_mark_node)
|
||||
type = got_object;
|
||||
|
||||
if (type)
|
||||
{
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
if (TYPE_P (type))
|
||||
type = complete_type (type);
|
||||
|
||||
if (TREE_CODE (type) == VOID_TYPE)
|
||||
type = global_namespace;
|
||||
if (TREE_CODE (type) == NAMESPACE_DECL)
|
||||
{
|
||||
val = make_node (CPLUS_BINDING);
|
||||
flags |= LOOKUP_COMPLAIN;
|
||||
if (!qualified_lookup_using_namespace (name, type, val, flags))
|
||||
return NULL_TREE;
|
||||
val = select_decl (val, flags);
|
||||
}
|
||||
else if (! IS_AGGR_TYPE (type)
|
||||
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|
||||
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
|
||||
|| TREE_CODE (type) == TYPENAME_TYPE)
|
||||
/* Someone else will give an error about this if needed. */
|
||||
val = NULL_TREE;
|
||||
else if (type == current_class_type)
|
||||
val = IDENTIFIER_CLASS_VALUE (name);
|
||||
else
|
||||
{
|
||||
val = lookup_member (type, name, 0, prefer_type);
|
||||
if (!uses_template_parms (type))
|
||||
type_access_control (type, val);
|
||||
|
||||
/* Restore the containing TYPENAME_TYPE if we looked
|
||||
through it before. */
|
||||
if (got_scope && got_scope != type
|
||||
&& val && TREE_CODE (val) == TYPE_DECL
|
||||
&& TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE)
|
||||
{
|
||||
val = TREE_TYPE (val);
|
||||
val = build_typename_type (got_scope, name,
|
||||
TYPENAME_TYPE_FULLNAME (val),
|
||||
TREE_TYPE (val));
|
||||
val = TYPE_STUB_DECL (val);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
val = NULL_TREE;
|
||||
|
||||
if (got_scope)
|
||||
goto done;
|
||||
else if (got_object && val)
|
||||
{
|
||||
from_obj = val;
|
||||
val = NULL_TREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = lookup_flags (prefer_type, namespaces_only);
|
||||
/* If we're not parsing, we need to complain. */
|
||||
flags |= LOOKUP_COMPLAIN;
|
||||
}
|
||||
flags |= lookup_flags (prefer_type, namespaces_only);
|
||||
|
||||
/* First, look in non-namespace scopes. */
|
||||
|
||||
@ -6175,11 +6147,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
|
||||
else
|
||||
binding = NULL_TREE;
|
||||
|
||||
/* Handle access control on types from enclosing or base classes. */
|
||||
if (binding && ! yylex
|
||||
&& BINDING_LEVEL (t) && BINDING_LEVEL (t)->parm_flag == 2)
|
||||
type_access_control (BINDING_LEVEL (t)->this_class, binding);
|
||||
|
||||
if (binding
|
||||
&& (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
|
||||
{
|
||||
@ -6205,36 +6172,12 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (val)
|
||||
{
|
||||
/* This should only warn about types used in qualified-ids. */
|
||||
if (from_obj && from_obj != val)
|
||||
{
|
||||
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
|
||||
&& TREE_CODE (val) == TYPE_DECL
|
||||
&& ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
|
||||
pedwarn ("\
|
||||
lookup of `%D' in the scope of `%#T' (`%#D') \
|
||||
does not match lookup in the current scope (`%#D')",
|
||||
name, got_object, from_obj, val);
|
||||
|
||||
/* We don't change val to from_obj if got_object depends on
|
||||
template parms because that breaks implicit typename for
|
||||
destructor calls. */
|
||||
if (! uses_template_parms (got_object))
|
||||
val = from_obj;
|
||||
}
|
||||
|
||||
/* If we have a single function from a using decl, pull it out. */
|
||||
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
|
||||
val = OVL_FUNCTION (val);
|
||||
}
|
||||
else if (from_obj)
|
||||
val = from_obj;
|
||||
|
||||
if (val && TREE_CODE (val) == ALIAS_DECL)
|
||||
val = DECL_INITIAL (val);
|
||||
|
||||
return val;
|
||||
}
|
||||
@ -6243,7 +6186,7 @@ tree
|
||||
lookup_name_nonclass (name)
|
||||
tree name;
|
||||
{
|
||||
return lookup_name_real (name, 0, 1, 0);
|
||||
return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN);
|
||||
}
|
||||
|
||||
tree
|
||||
@ -6259,7 +6202,7 @@ lookup_name_namespace_only (name)
|
||||
tree name;
|
||||
{
|
||||
/* type-or-namespace, nonclass, namespace_only */
|
||||
return lookup_name_real (name, 1, 1, 1);
|
||||
return lookup_name_real (name, 1, 1, 1, LOOKUP_COMPLAIN);
|
||||
}
|
||||
|
||||
tree
|
||||
@ -6267,7 +6210,7 @@ lookup_name (name, prefer_type)
|
||||
tree name;
|
||||
int prefer_type;
|
||||
{
|
||||
return lookup_name_real (name, prefer_type, 0, 0);
|
||||
return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN);
|
||||
}
|
||||
|
||||
/* Similar to `lookup_name' but look only in the innermost non-class
|
||||
@ -7062,9 +7005,9 @@ fixup_anonymous_aggr (t)
|
||||
}
|
||||
|
||||
/* Make sure that a declaration with no declarator is well-formed, i.e.
|
||||
just defines a tagged type or anonymous union.
|
||||
just declares a tagged type or anonymous union.
|
||||
|
||||
Returns the type defined, if any. */
|
||||
Returns the type declared; or NULL_TREE if none. */
|
||||
|
||||
tree
|
||||
check_tag_decl (declspecs)
|
||||
@ -7075,11 +7018,16 @@ check_tag_decl (declspecs)
|
||||
int saw_typedef = 0;
|
||||
tree ob_modifier = NULL_TREE;
|
||||
register tree link;
|
||||
register tree t = NULL_TREE;
|
||||
/* If a class, struct, or enum type is declared by the DECLSPECS
|
||||
(i.e, if a class-specifier, enum-specifier, or non-typename
|
||||
elaborated-type-specifier appears in the DECLSPECS),
|
||||
DECLARED_TYPE is set to the corresponding type. */
|
||||
tree declared_type = NULL_TREE;
|
||||
bool error_p = false;
|
||||
|
||||
for (link = declspecs; link; link = TREE_CHAIN (link))
|
||||
{
|
||||
register tree value = TREE_VALUE (link);
|
||||
tree value = TREE_VALUE (link);
|
||||
|
||||
if (TYPE_P (value)
|
||||
|| TREE_CODE (value) == TYPE_DECL
|
||||
@ -7101,7 +7049,7 @@ check_tag_decl (declspecs)
|
||||
|| TREE_CODE (value) == ENUMERAL_TYPE))
|
||||
{
|
||||
my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
|
||||
t = value;
|
||||
declared_type = value;
|
||||
}
|
||||
}
|
||||
else if (value == ridpointers[(int) RID_TYPEDEF])
|
||||
@ -7125,17 +7073,18 @@ check_tag_decl (declspecs)
|
||||
|| value == ridpointers[(int) RID_EXPLICIT]
|
||||
|| value == ridpointers[(int) RID_THREAD])
|
||||
ob_modifier = value;
|
||||
else if (value == error_mark_node)
|
||||
error_p = true;
|
||||
}
|
||||
|
||||
if (found_type > 1)
|
||||
error ("multiple types in one declaration");
|
||||
|
||||
if (t == NULL_TREE && ! saw_friend)
|
||||
if (declared_type == NULL_TREE && ! saw_friend && !error_p)
|
||||
pedwarn ("declaration does not declare anything");
|
||||
|
||||
/* Check for an anonymous union. */
|
||||
else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
|
||||
&& TYPE_ANONYMOUS_P (t))
|
||||
else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type))
|
||||
&& TYPE_ANONYMOUS_P (declared_type))
|
||||
{
|
||||
/* 7/3 In a simple-declaration, the optional init-declarator-list
|
||||
can be omitted only when declaring a class (clause 9) or
|
||||
@ -7159,9 +7108,10 @@ check_tag_decl (declspecs)
|
||||
return NULL_TREE;
|
||||
}
|
||||
/* Anonymous unions are objects, so they can have specifiers. */;
|
||||
SET_ANON_AGGR_TYPE_P (t);
|
||||
SET_ANON_AGGR_TYPE_P (declared_type);
|
||||
|
||||
if (TREE_CODE (t) != UNION_TYPE && pedantic && ! in_system_header)
|
||||
if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
|
||||
&& !in_system_header)
|
||||
pedwarn ("ISO C++ prohibits anonymous structs");
|
||||
}
|
||||
|
||||
@ -7180,7 +7130,7 @@ check_tag_decl (declspecs)
|
||||
ob_modifier);
|
||||
}
|
||||
|
||||
return t;
|
||||
return declared_type;
|
||||
}
|
||||
|
||||
/* Called when a declaration is seen that contains no names to declare.
|
||||
@ -7192,23 +7142,27 @@ check_tag_decl (declspecs)
|
||||
Otherwise, it is an error.
|
||||
|
||||
C++: may have to grok the declspecs to learn about static,
|
||||
complain for anonymous unions. */
|
||||
complain for anonymous unions.
|
||||
|
||||
void
|
||||
Returns the TYPE declared -- or NULL_TREE if none. */
|
||||
|
||||
tree
|
||||
shadow_tag (declspecs)
|
||||
tree declspecs;
|
||||
{
|
||||
tree t = check_tag_decl (declspecs);
|
||||
|
||||
if (t)
|
||||
maybe_process_partial_specialization (t);
|
||||
if (!t)
|
||||
return NULL_TREE;
|
||||
|
||||
maybe_process_partial_specialization (t);
|
||||
|
||||
/* This is where the variables in an anonymous union are
|
||||
declared. An anonymous union declaration looks like:
|
||||
union { ... } ;
|
||||
because there is no declarator after the union, the parser
|
||||
sends that declaration here. */
|
||||
if (t && ANON_AGGR_TYPE_P (t))
|
||||
if (ANON_AGGR_TYPE_P (t))
|
||||
{
|
||||
fixup_anonymous_aggr (t);
|
||||
|
||||
@ -7219,6 +7173,8 @@ shadow_tag (declspecs)
|
||||
finish_anon_union (decl);
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
|
||||
@ -7374,9 +7330,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
|
||||
{
|
||||
if (DECL_CONTEXT (field) != context)
|
||||
{
|
||||
pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
|
||||
DECL_CONTEXT (field), DECL_NAME (decl),
|
||||
context, DECL_NAME (decl));
|
||||
if (!same_type_p (DECL_CONTEXT (field), context))
|
||||
pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
|
||||
DECL_CONTEXT (field), DECL_NAME (decl),
|
||||
context, DECL_NAME (decl));
|
||||
DECL_CONTEXT (decl) = DECL_CONTEXT (field);
|
||||
}
|
||||
/* Static data member are tricky; an in-class initialization
|
||||
@ -7529,9 +7486,6 @@ grok_reference_init (decl, type, init)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (init == error_mark_node)
|
||||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
{
|
||||
error ("ISO C++ forbids use of initializer list to initialize reference `%D'", decl);
|
||||
@ -8800,7 +8754,6 @@ register_dtor_fn (decl)
|
||||
tree compound_stmt;
|
||||
tree args;
|
||||
tree fcall;
|
||||
|
||||
int saved_flag_access_control;
|
||||
|
||||
if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
|
||||
@ -8819,9 +8772,9 @@ register_dtor_fn (decl)
|
||||
will make the back-end think that nested functions are in use,
|
||||
which causes confusion. */
|
||||
saved_flag_access_control = flag_access_control;
|
||||
flag_access_control = 0;
|
||||
scope_chain->check_access = flag_access_control = 0;
|
||||
fcall = build_cleanup (decl);
|
||||
flag_access_control = saved_flag_access_control;
|
||||
scope_chain->check_access = flag_access_control = saved_flag_access_control;
|
||||
|
||||
/* Create the body of the anonymous function. */
|
||||
compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
|
||||
@ -9333,9 +9286,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
||||
}
|
||||
}
|
||||
|
||||
if (has_default_arg)
|
||||
add_defarg_fn (decl);
|
||||
|
||||
if (funcdef_flag)
|
||||
/* Make the init_value nonzero so pushdecl knows this is not
|
||||
tentative. error_mark_node is replaced later with the BLOCK. */
|
||||
@ -9348,7 +9298,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
|
||||
if (check < 0)
|
||||
return decl;
|
||||
|
||||
if (flags == NO_SPECIAL && ctype && constructor_name (ctype) == declarator)
|
||||
if (flags == NO_SPECIAL && ctype && constructor_name_p (declarator, ctype))
|
||||
DECL_CONSTRUCTOR_P (decl) = 1;
|
||||
|
||||
/* Function gets the ugly name, field gets the nice one. This call
|
||||
@ -9782,6 +9732,48 @@ compute_array_index_type (name, size)
|
||||
return build_index_type (itype);
|
||||
}
|
||||
|
||||
/* Returns the scope (if any) in which the entity declared by
|
||||
DECLARATOR will be located. If the entity was declared with an
|
||||
unqualified name, NULL_TREE is returned. */
|
||||
|
||||
tree
|
||||
get_scope_of_declarator (declarator)
|
||||
tree declarator;
|
||||
{
|
||||
if (!declarator)
|
||||
return NULL_TREE;
|
||||
|
||||
switch (TREE_CODE (declarator))
|
||||
{
|
||||
case CALL_EXPR:
|
||||
case ARRAY_REF:
|
||||
case INDIRECT_REF:
|
||||
case ADDR_EXPR:
|
||||
/* For any of these, the main declarator is the first operand. */
|
||||
return get_scope_of_declarator (TREE_OPERAND
|
||||
(declarator, 0));
|
||||
|
||||
case SCOPE_REF:
|
||||
/* For a pointer-to-member, continue descending. */
|
||||
if (TREE_CODE (TREE_OPERAND (declarator, 1))
|
||||
== INDIRECT_REF)
|
||||
return get_scope_of_declarator (TREE_OPERAND
|
||||
(declarator, 1));
|
||||
/* Otherwise, if the declarator-id is a SCOPE_REF, the scope in
|
||||
which the declaration occurs is the first operand. */
|
||||
return TREE_OPERAND (declarator, 0);
|
||||
|
||||
case TREE_LIST:
|
||||
/* Attributes to be applied. The declarator is TREE_VALUE. */
|
||||
return get_scope_of_declarator (TREE_VALUE (declarator));
|
||||
|
||||
default:
|
||||
/* Otherwise, we have a declarator-id which is not a qualified
|
||||
name; the entity will be declared in the current scope. */
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns an ARRAY_TYPE for an array with SIZE elements of the
|
||||
indicated TYPE. If non-NULL, NAME is the NAME of the declaration
|
||||
with this type. */
|
||||
@ -9906,11 +9898,9 @@ check_special_function_return_type (sfk, type, optype)
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Given declspecs and a declarator,
|
||||
determine the name and type of the object declared
|
||||
and construct a ..._DECL node for it.
|
||||
(In one case we can return a ..._TYPE node instead.
|
||||
For invalid input we sometimes return 0.)
|
||||
/* Given declspecs and a declarator (abstract or otherwise), determine
|
||||
the name and type of the object declared and construct a DECL node
|
||||
for it.
|
||||
|
||||
DECLSPECS is a chain of tree_list nodes whose value fields
|
||||
are the storage classes and type specifiers.
|
||||
@ -9937,35 +9927,15 @@ check_special_function_return_type (sfk, type, optype)
|
||||
if there are none; *ATTRLIST may be modified if attributes from inside
|
||||
the declarator should be applied to the declaration.
|
||||
|
||||
In the TYPENAME case, DECLARATOR is really an abstract declarator.
|
||||
It may also be so in the PARM case, for a prototype where the
|
||||
argument type is specified but not the name.
|
||||
When this function is called, scoping variables (such as
|
||||
CURRENT_CLASS_TYPE) should reflect the scope in which the
|
||||
declaration occurs, not the scope in which the new declaration will
|
||||
be placed. For example, on:
|
||||
|
||||
This function is where the complicated C meanings of `static'
|
||||
and `extern' are interpreted.
|
||||
void S::f() { ... }
|
||||
|
||||
For C++, if there is any monkey business to do, the function which
|
||||
calls this one must do it, i.e., prepending instance variables,
|
||||
renaming overloaded function names, etc.
|
||||
|
||||
Note that for this C++, it is an error to define a method within a class
|
||||
which does not belong to that class.
|
||||
|
||||
Except in the case where SCOPE_REFs are implicitly known (such as
|
||||
methods within a class being redundantly qualified),
|
||||
declarations which involve SCOPE_REFs are returned as SCOPE_REFs
|
||||
(class_name::decl_name). The caller must also deal with this.
|
||||
|
||||
If a constructor or destructor is seen, and the context is FIELD,
|
||||
then the type gains the attribute TREE_HAS_x. If such a declaration
|
||||
is erroneous, NULL_TREE is returned.
|
||||
|
||||
QUALS is used only for FUNCDEF and MEMFUNCDEF cases. For a member
|
||||
function, these are the qualifiers to give to the `this' pointer. We
|
||||
apply TYPE_QUAL_RESTRICT to the this ptr, not the object.
|
||||
|
||||
May return void_type_node if the declarator turned out to be a friend.
|
||||
See grokfield for details. */
|
||||
when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
|
||||
should not be `S'. */
|
||||
|
||||
tree
|
||||
grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
@ -10016,6 +9986,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
int template_count = 0;
|
||||
tree in_namespace = NULL_TREE;
|
||||
tree returned_attrs = NULL_TREE;
|
||||
tree scope = NULL_TREE;
|
||||
|
||||
RIDBIT_RESET_ALL (specbits);
|
||||
if (decl_context == FUNCDEF)
|
||||
@ -10055,7 +10026,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
my_friendly_assert (flags == NO_SPECIAL, 152);
|
||||
flags = DTOR_FLAG;
|
||||
sfk = sfk_destructor;
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
if (TYPE_P (name))
|
||||
TREE_OPERAND (decl, 0) = name = constructor_name (name);
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
|
||||
if (ctype == NULL_TREE)
|
||||
@ -10067,7 +10038,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
}
|
||||
else
|
||||
{
|
||||
tree t = constructor_name (current_class_name);
|
||||
tree t = constructor_name (current_class_type);
|
||||
if (t != name)
|
||||
rename = t;
|
||||
}
|
||||
@ -10153,7 +10124,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
decl = *next;
|
||||
if (ctype != NULL_TREE
|
||||
&& decl != NULL_TREE && flags != DTOR_FLAG
|
||||
&& decl == constructor_name (ctype))
|
||||
&& constructor_name_p (decl, ctype))
|
||||
{
|
||||
sfk = sfk_constructor;
|
||||
ctor_return_type = ctype;
|
||||
@ -10220,10 +10191,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
{
|
||||
ctype = NULL_TREE;
|
||||
in_namespace = TREE_OPERAND (decl, 0);
|
||||
TREE_OPERAND (decl, 0) = NULL_TREE;
|
||||
}
|
||||
else if (! is_aggr_type (cname, 1))
|
||||
TREE_OPERAND (decl, 0) = NULL_TREE;
|
||||
ctype = NULL_TREE;
|
||||
/* Must test TREE_OPERAND (decl, 1), in case user gives
|
||||
us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */
|
||||
else if (TREE_OPERAND (decl, 1)
|
||||
@ -10240,19 +10210,35 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
else if (ctype == NULL_TREE)
|
||||
ctype = cname;
|
||||
else if (TREE_COMPLEXITY (decl) == current_class_depth)
|
||||
TREE_OPERAND (decl, 0) = ctype;
|
||||
;
|
||||
else
|
||||
{
|
||||
if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
|
||||
{
|
||||
error ("type `%T' is not derived from type `%T'",
|
||||
cname, ctype);
|
||||
TREE_OPERAND (decl, 0) = NULL_TREE;
|
||||
ctype = NULL_TREE;
|
||||
}
|
||||
else
|
||||
ctype = cname;
|
||||
}
|
||||
|
||||
/* It is valid to write:
|
||||
|
||||
class C { void f(); };
|
||||
typedef C D;
|
||||
void D::f();
|
||||
|
||||
The standard is not clear about whether `typedef const C D' is
|
||||
legal; as of 2002-09-15 the committee is considering
|
||||
that question. EDG 3.0 allows that syntax.
|
||||
Therefore, we do as well. */
|
||||
if (ctype)
|
||||
ctype = TYPE_MAIN_VARIANT (ctype);
|
||||
/* Update the declarator so that when we process it
|
||||
again the correct type is present. */
|
||||
TREE_OPERAND (decl, 0) = ctype;
|
||||
|
||||
if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
|
||||
&& constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)),
|
||||
ctype))
|
||||
@ -10262,7 +10248,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
if (ctype)
|
||||
{
|
||||
if (TREE_CODE (decl) == IDENTIFIER_NODE
|
||||
&& constructor_name (ctype) == decl)
|
||||
&& constructor_name_p (decl, ctype))
|
||||
{
|
||||
sfk = sfk_constructor;
|
||||
ctor_return_type = ctype;
|
||||
@ -10890,6 +10876,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
if (nclasses > 0 && friendp)
|
||||
error ("storage class specifiers invalid in friend function declarations");
|
||||
|
||||
scope = get_scope_of_declarator (declarator);
|
||||
|
||||
/* Now figure out the structure of the declarator proper.
|
||||
Descend through it, creating more complex types, until we reach
|
||||
the declared identifier (or NULL_TREE, in an abstract declarator). */
|
||||
@ -10937,7 +10925,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
|
||||
grok_method_quals (ctype, dummy, quals);
|
||||
type = TREE_TYPE (dummy);
|
||||
ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)));
|
||||
quals = NULL_TREE;
|
||||
}
|
||||
}
|
||||
@ -11045,7 +11032,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
|
||||
if (ctype && sfk == sfk_conversion)
|
||||
TYPE_HAS_CONVERSION (ctype) = 1;
|
||||
if (ctype && constructor_name (ctype) == dname)
|
||||
if (ctype && constructor_name_p (dname, ctype))
|
||||
{
|
||||
/* We are within a class's scope. If our declarator name
|
||||
is the same as the class name, and we are defining
|
||||
@ -11163,17 +11150,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
/* ANSI says that `const int foo ();'
|
||||
does not make the function foo const. */
|
||||
type = build_function_type (type, arg_types);
|
||||
|
||||
{
|
||||
tree t;
|
||||
for (t = arg_types; t; t = TREE_CHAIN (t))
|
||||
if (TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
|
||||
{
|
||||
add_defarg_fn (type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -11278,44 +11254,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
if (TREE_CODE (sname) == BIT_NOT_EXPR)
|
||||
sname = TREE_OPERAND (sname, 0);
|
||||
|
||||
if (TREE_COMPLEXITY (declarator) == 0)
|
||||
/* This needs to be here, in case we are called
|
||||
multiple times. */ ;
|
||||
else if (TREE_COMPLEXITY (declarator) == -1)
|
||||
/* Namespace member. */
|
||||
pop_decl_namespace ();
|
||||
else if (friendp && (TREE_COMPLEXITY (declarator) < 2))
|
||||
/* Don't fall out into global scope. Hides real bug? --eichin */ ;
|
||||
else if (!TREE_OPERAND (declarator, 0)
|
||||
|| !IS_AGGR_TYPE_CODE
|
||||
(TREE_CODE (TREE_OPERAND (declarator, 0))))
|
||||
;
|
||||
else if (TREE_COMPLEXITY (declarator) == current_class_depth)
|
||||
{
|
||||
/* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
|
||||
that refer to ctype. They couldn't be resolved earlier
|
||||
because we hadn't pushed into the class yet.
|
||||
Example: resolve 'B<T>::type' in
|
||||
'B<typename B<T>::type> B<T>::f () { }'. */
|
||||
if (current_template_parms
|
||||
&& uses_template_parms (type)
|
||||
&& uses_template_parms (current_class_type))
|
||||
{
|
||||
tree args = current_template_args ();
|
||||
type = tsubst (type, args, tf_error | tf_warning,
|
||||
NULL_TREE);
|
||||
}
|
||||
|
||||
/* This pop_nested_class corresponds to the
|
||||
push_nested_class used to push into class scope for
|
||||
parsing the argument list of a function decl, in
|
||||
qualified_id. */
|
||||
pop_nested_class ();
|
||||
TREE_COMPLEXITY (declarator) = current_class_depth;
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
|
||||
if (TREE_OPERAND (declarator, 0) == NULL_TREE)
|
||||
{
|
||||
/* We had a reference to a global decl, or
|
||||
@ -11379,7 +11317,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
{
|
||||
error ("cannot declare member function `%T::%s' within `%T'",
|
||||
ctype, name, current_class_type);
|
||||
return void_type_node;
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
|
||||
@ -11452,6 +11390,35 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
attrlist = &returned_attrs;
|
||||
}
|
||||
|
||||
/* Resolve any TYPENAME_TYPEs from the decl-specifier-seq that refer
|
||||
to ctype. They couldn't be resolved earlier because we hadn't
|
||||
pushed into the class yet.
|
||||
|
||||
For example, consider:
|
||||
|
||||
template <typename T>
|
||||
struct S {
|
||||
typedef T X;
|
||||
X f();
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename S<T>::X f() {}
|
||||
|
||||
When parsing the decl-specifier-seq for the definition of `f',
|
||||
we construct a TYPENAME_TYPE for `S<T>::X'. By substituting
|
||||
here, we resolve it to the correct type. */
|
||||
if (scope && CLASS_TYPE_P (scope)
|
||||
&& current_template_parms
|
||||
&& uses_template_parms (scope))
|
||||
{
|
||||
tree args = current_template_args ();
|
||||
push_scope (scope);
|
||||
type = tsubst (type, args, tf_error | tf_warning,
|
||||
NULL_TREE);
|
||||
pop_scope (scope);
|
||||
}
|
||||
|
||||
/* Now TYPE has the actual type. */
|
||||
|
||||
/* Did array size calculations overflow? */
|
||||
@ -11540,7 +11507,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
|
||||
if (decl_context == FIELD)
|
||||
{
|
||||
if (declarator == constructor_name (current_class_type))
|
||||
if (constructor_name_p (declarator, current_class_type))
|
||||
pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
|
||||
declarator);
|
||||
decl = build_lang_decl (TYPE_DECL, declarator, type);
|
||||
@ -11548,6 +11515,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
else
|
||||
{
|
||||
decl = build_decl (TYPE_DECL, declarator, type);
|
||||
if (in_namespace || ctype)
|
||||
cp_error_at ("typedef name may not be a nested-name-specifier",
|
||||
decl);
|
||||
if (!current_function_decl)
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
|
||||
}
|
||||
@ -11588,12 +11558,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
type with external linkage have external linkage. */
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
cp_error_at ("typedef name may not be class-qualified", decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (quals)
|
||||
if (quals)
|
||||
{
|
||||
if (ctype == NULL_TREE)
|
||||
{
|
||||
@ -12011,7 +11976,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
||||
}
|
||||
|
||||
/* 9.2p13 [class.mem] */
|
||||
if (declarator == constructor_name (current_class_type)
|
||||
if (constructor_name_p (declarator, current_class_type)
|
||||
/* The standard does not allow non-static data members
|
||||
here either, but we agreed at the 10/99 meeting
|
||||
to change that in TC 1 so that they are allowed in
|
||||
@ -14616,9 +14581,14 @@ start_method (declspecs, declarator, attrlist)
|
||||
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
|
||||
&attrlist);
|
||||
|
||||
/* Something too ugly to handle. */
|
||||
if (fndecl == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
if (fndecl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
|
||||
{
|
||||
error ("invalid member function declaration");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (attrlist)
|
||||
cplus_decl_attributes (&fndecl, attrlist, 0);
|
||||
@ -14627,10 +14597,6 @@ start_method (declspecs, declarator, attrlist)
|
||||
if (fndecl == void_type_node)
|
||||
return fndecl;
|
||||
|
||||
if (TREE_CODE (fndecl) != FUNCTION_DECL)
|
||||
/* Not a function, tell parser to report parse error. */
|
||||
return NULL_TREE;
|
||||
|
||||
if (DECL_IN_AGGR_P (fndecl))
|
||||
{
|
||||
if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
|
||||
@ -14908,7 +14874,7 @@ cp_tree_node_structure (t)
|
||||
{
|
||||
switch (TREE_CODE (&t->generic))
|
||||
{
|
||||
case DEFAULT_ARG: return TS_CP_IDENTIFIER;
|
||||
case DEFAULT_ARG: return TS_CP_DEFAULT_ARG;
|
||||
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
|
||||
case CPLUS_BINDING: return TS_CP_BINDING;
|
||||
case OVERLOAD: return TS_CP_OVERLOAD;
|
||||
|
238
gcc/cp/decl2.c
238
gcc/cp/decl2.c
@ -1220,51 +1220,34 @@ cplus_decl_attributes (decl, attributes, flags)
|
||||
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
|
||||
}
|
||||
|
||||
/* CONSTRUCTOR_NAME:
|
||||
Return the name for the constructor (or destructor) for the
|
||||
specified class. Argument can be RECORD_TYPE, TYPE_DECL, or
|
||||
IDENTIFIER_NODE. When given a template, this routine doesn't
|
||||
/* Return the name for the constructor (or destructor) for the
|
||||
specified class TYPE. When given a template, this routine doesn't
|
||||
lose the specialization. */
|
||||
|
||||
tree
|
||||
constructor_name_full (thing)
|
||||
tree thing;
|
||||
constructor_name_full (tree type)
|
||||
{
|
||||
if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM
|
||||
|| TREE_CODE (thing) == BOUND_TEMPLATE_TEMPLATE_PARM
|
||||
|| TREE_CODE (thing) == TYPENAME_TYPE)
|
||||
thing = TYPE_NAME (thing);
|
||||
else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
|
||||
{
|
||||
if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
|
||||
thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0)));
|
||||
else
|
||||
thing = TYPE_NAME (thing);
|
||||
}
|
||||
if (TREE_CODE (thing) == TYPE_DECL
|
||||
|| (TREE_CODE (thing) == TEMPLATE_DECL
|
||||
&& TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL))
|
||||
thing = DECL_NAME (thing);
|
||||
my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197);
|
||||
return thing;
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type)
|
||||
&& TYPE_HAS_CONSTRUCTOR (type))
|
||||
return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
|
||||
else
|
||||
return TYPE_IDENTIFIER (type);
|
||||
}
|
||||
|
||||
/* CONSTRUCTOR_NAME:
|
||||
Return the name for the constructor (or destructor) for the
|
||||
specified class. Argument can be RECORD_TYPE, TYPE_DECL, or
|
||||
IDENTIFIER_NODE. When given a template, return the plain
|
||||
/* Return the name for the constructor (or destructor) for the
|
||||
specified class. When given a template, return the plain
|
||||
unspecialized name. */
|
||||
|
||||
tree
|
||||
constructor_name (thing)
|
||||
tree thing;
|
||||
constructor_name (type)
|
||||
tree type;
|
||||
{
|
||||
tree t;
|
||||
thing = constructor_name_full (thing);
|
||||
t = IDENTIFIER_TEMPLATE (thing);
|
||||
if (!t)
|
||||
return thing;
|
||||
return t;
|
||||
tree name;
|
||||
name = constructor_name_full (type);
|
||||
if (IDENTIFIER_TEMPLATE (name))
|
||||
name = IDENTIFIER_TEMPLATE (name);
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Returns TRUE if NAME is the name for the constructor for TYPE. */
|
||||
@ -3036,7 +3019,12 @@ build_expr_from_tree (t)
|
||||
return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token));
|
||||
}
|
||||
else
|
||||
return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
|
||||
{
|
||||
t = do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
|
||||
if (TREE_CODE (t) == ALIAS_DECL)
|
||||
t = DECL_INITIAL (t);
|
||||
return t;
|
||||
}
|
||||
|
||||
case TEMPLATE_ID_EXPR:
|
||||
{
|
||||
@ -3292,7 +3280,7 @@ build_expr_from_tree (t)
|
||||
build_expr_from_tree (TREE_OPERAND (t, 2)));
|
||||
|
||||
case PSEUDO_DTOR_EXPR:
|
||||
return (finish_pseudo_destructor_call_expr
|
||||
return (finish_pseudo_destructor_expr
|
||||
(build_expr_from_tree (TREE_OPERAND (t, 0)),
|
||||
build_expr_from_tree (TREE_OPERAND (t, 1)),
|
||||
build_expr_from_tree (TREE_OPERAND (t, 2))));
|
||||
@ -3319,8 +3307,48 @@ build_expr_from_tree (t)
|
||||
case COMPONENT_REF:
|
||||
{
|
||||
tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
|
||||
return finish_class_member_access_expr (object,
|
||||
TREE_OPERAND (t, 1));
|
||||
tree member = TREE_OPERAND (t, 1);
|
||||
|
||||
if (!CLASS_TYPE_P (TREE_TYPE (object)))
|
||||
{
|
||||
if (TREE_CODE (member) == BIT_NOT_EXPR)
|
||||
return finish_pseudo_destructor_expr (object,
|
||||
NULL_TREE,
|
||||
TREE_TYPE (object));
|
||||
else if (TREE_CODE (member) == SCOPE_REF
|
||||
&& (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
|
||||
return finish_pseudo_destructor_expr (object,
|
||||
TREE_OPERAND (t, 0),
|
||||
TREE_TYPE (object));
|
||||
}
|
||||
else if (TREE_CODE (member) == SCOPE_REF
|
||||
&& TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
tree tmpl;
|
||||
tree args;
|
||||
|
||||
/* Lookup the template functions now that we know what the
|
||||
scope is. */
|
||||
tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
|
||||
args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
|
||||
member = lookup_qualified_name (TREE_OPERAND (member, 0),
|
||||
tmpl,
|
||||
/*is_type=*/0,
|
||||
/*flags=*/0);
|
||||
if (BASELINK_P (member))
|
||||
BASELINK_FUNCTIONS (member)
|
||||
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
|
||||
args);
|
||||
else
|
||||
{
|
||||
error ("`%D' is not a member of `%T'",
|
||||
tmpl, TREE_TYPE (object));
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return finish_class_member_access_expr (object, member);
|
||||
}
|
||||
|
||||
case THROW_EXPR:
|
||||
@ -3366,6 +3394,7 @@ build_expr_from_tree (t)
|
||||
return get_typeid (TREE_OPERAND (t, 0));
|
||||
return build_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
|
||||
|
||||
case PARM_DECL:
|
||||
case VAR_DECL:
|
||||
return convert_from_reference (t);
|
||||
|
||||
@ -3857,13 +3886,19 @@ set_decl_namespace (decl, scope, friendp)
|
||||
if (!is_overloaded_fn (old))
|
||||
goto complain;
|
||||
if (processing_template_decl || processing_specialization)
|
||||
/* We have not yet called push_template_decl to turn the
|
||||
/* We have not yet called push_template_decl to turn a
|
||||
FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
|
||||
won't match. But, we'll check later, when we construct the
|
||||
template. */
|
||||
return;
|
||||
for (; old; old = OVL_NEXT (old))
|
||||
if (decls_match (decl, OVL_CURRENT (old)))
|
||||
if (is_overloaded_fn (old))
|
||||
{
|
||||
for (; old; old = OVL_NEXT (old))
|
||||
if (decls_match (decl, OVL_CURRENT (old)))
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (decls_match (decl, old))
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -3939,8 +3974,8 @@ push_scope (t)
|
||||
{
|
||||
if (TREE_CODE (t) == NAMESPACE_DECL)
|
||||
push_decl_namespace (t);
|
||||
else
|
||||
pushclass (t, 2);
|
||||
else if CLASS_TYPE_P (t)
|
||||
push_nested_class (t, 2);
|
||||
}
|
||||
|
||||
/* Leave scope pushed by push_scope. */
|
||||
@ -3951,8 +3986,8 @@ pop_scope (t)
|
||||
{
|
||||
if (TREE_CODE (t) == NAMESPACE_DECL)
|
||||
pop_decl_namespace ();
|
||||
else
|
||||
popclass ();
|
||||
else if CLASS_TYPE_P (t)
|
||||
pop_nested_class ();
|
||||
}
|
||||
|
||||
/* [basic.lookup.koenig] */
|
||||
@ -4340,52 +4375,47 @@ validate_nonmember_using_decl (decl, scope, name)
|
||||
tree *scope;
|
||||
tree *name;
|
||||
{
|
||||
if (TREE_CODE (decl) == SCOPE_REF)
|
||||
{
|
||||
*scope = TREE_OPERAND (decl, 0);
|
||||
*name = TREE_OPERAND (decl, 1);
|
||||
*scope = global_namespace;
|
||||
*name = NULL_TREE;
|
||||
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
/* [namespace.udecl]
|
||||
A using-declaration for a class member shall be a
|
||||
member-declaration. */
|
||||
if(TREE_CODE (*scope) != NAMESPACE_DECL)
|
||||
{
|
||||
if (TYPE_P (*scope))
|
||||
error ("`%T' is not a namespace", *scope);
|
||||
else
|
||||
error ("`%D' is not a namespace", *scope);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* 7.3.3/5
|
||||
A using-declaration shall not name a template-id. */
|
||||
if (TREE_CODE (*name) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
*name = TREE_OPERAND (*name, 0);
|
||||
error ("a using-declaration cannot specify a template-id. Try `using %D'", *name);
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (decl) == IDENTIFIER_NODE
|
||||
|| TREE_CODE (decl) == TYPE_DECL
|
||||
|| TREE_CODE (decl) == TEMPLATE_DECL)
|
||||
if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
*scope = global_namespace;
|
||||
*name = decl;
|
||||
*name = TREE_OPERAND (decl, 0);
|
||||
/* 7.3.3/5
|
||||
A using-declaration shall not name a template-id. */
|
||||
error ("a using-declaration cannot specify a template-id. Try `using %D'", *name);
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (TREE_CODE (decl) == NAMESPACE_DECL)
|
||||
|
||||
if (TREE_CODE (decl) == NAMESPACE_DECL)
|
||||
{
|
||||
error ("namespace `%D' not allowed in using-declaration", decl);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (is_overloaded_fn (decl))
|
||||
decl = get_first_fn (decl);
|
||||
|
||||
my_friendly_assert (DECL_P (decl), 20020908);
|
||||
|
||||
if (TREE_CODE (decl) == CONST_DECL)
|
||||
/* Enumeration constants to not have DECL_CONTEXT set. */
|
||||
*scope = TYPE_CONTEXT (TREE_TYPE (decl));
|
||||
else
|
||||
abort ();
|
||||
if (DECL_P (*name))
|
||||
*name = DECL_NAME (*name);
|
||||
/* Make a USING_DECL. */
|
||||
*scope = DECL_CONTEXT (decl);
|
||||
if (!*scope)
|
||||
*scope = global_namespace;
|
||||
|
||||
/* [namespace.udecl]
|
||||
A using-declaration for a class member shall be a
|
||||
member-declaration. */
|
||||
if (TYPE_P (*scope))
|
||||
{
|
||||
error ("`%T' is not a namespace", *scope);
|
||||
return NULL_TREE;
|
||||
}
|
||||
*name = DECL_NAME (decl);
|
||||
/* Make a USING_DECL. */
|
||||
return push_using_decl (*scope, *name);
|
||||
}
|
||||
|
||||
@ -4591,14 +4621,32 @@ do_class_using_decl (decl)
|
||||
error ("a using-declaration cannot specify a template-id. Try `using %T::%D'", TREE_OPERAND (decl, 0), name);
|
||||
return NULL_TREE;
|
||||
}
|
||||
if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL)
|
||||
name = DECL_NAME (name);
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
{
|
||||
tree type = TREE_TYPE (name);
|
||||
if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name)))
|
||||
{
|
||||
name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
|
||||
error ("a using-declaration cannot specify a template-id.");
|
||||
return NULL_TREE;
|
||||
}
|
||||
name = DECL_NAME (name);
|
||||
}
|
||||
else if (TREE_CODE (name) == TEMPLATE_DECL)
|
||||
name = DECL_NAME (name);
|
||||
else if (BASELINK_P (name))
|
||||
{
|
||||
name = BASELINK_FUNCTIONS (name);
|
||||
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
||||
name = TREE_OPERAND (name, 0);
|
||||
name = DECL_NAME (get_first_fn (name));
|
||||
tree fns;
|
||||
|
||||
fns = BASELINK_FUNCTIONS (name);
|
||||
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
fns = TREE_OPERAND (fns, 0);
|
||||
error ("a using-declaration cannot specify a template-id. Try `using %T::%D'",
|
||||
BASELINK_ACCESS_BINFO (name),
|
||||
DECL_NAME (get_first_fn (fns)));
|
||||
}
|
||||
name = DECL_NAME (get_first_fn (fns));
|
||||
}
|
||||
|
||||
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
|
||||
@ -4785,13 +4833,9 @@ handle_class_head (tag_kind, scope, id, attributes, defn_p, new_type_p)
|
||||
if (*new_type_p)
|
||||
push_scope (context);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
|
||||
/* It is valid to define a class with a different class key,
|
||||
and this changes the default member access. */
|
||||
CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl))
|
||||
= (tag_kind == class_type);
|
||||
|
||||
if (!xrefd_p && PROCESSING_REAL_TEMPLATE_DECL_P ())
|
||||
if (!xrefd_p
|
||||
&& PROCESSING_REAL_TEMPLATE_DECL_P ()
|
||||
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
|
||||
decl = push_template_decl (decl);
|
||||
}
|
||||
|
||||
|
@ -1439,6 +1439,7 @@ dump_expr (t, flags)
|
||||
case TEMPLATE_DECL:
|
||||
case NAMESPACE_DECL:
|
||||
case OVERLOAD:
|
||||
case IDENTIFIER_NODE:
|
||||
dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
|
||||
break;
|
||||
|
||||
@ -1913,10 +1914,6 @@ dump_expr (t, flags)
|
||||
dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
|
||||
break;
|
||||
|
||||
case IDENTIFIER_NODE:
|
||||
print_tree_identifier (scratch_buffer, t);
|
||||
break;
|
||||
|
||||
case SCOPE_REF:
|
||||
dump_type (TREE_OPERAND (t, 0), flags);
|
||||
print_scope_operator (scratch_buffer);
|
||||
@ -2031,12 +2028,10 @@ dump_expr (t, flags)
|
||||
output_add_string (scratch_buffer, ") break; ");
|
||||
break;
|
||||
|
||||
case TREE_LIST:
|
||||
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
|
||||
{
|
||||
print_tree_identifier (scratch_buffer, DECL_NAME (TREE_VALUE (t)));
|
||||
break;
|
||||
}
|
||||
case BASELINK:
|
||||
print_tree_identifier (scratch_buffer, DECL_NAME (get_first_fn (t)));
|
||||
break;
|
||||
|
||||
/* else fall through */
|
||||
|
||||
/* This list is incomplete, but should suffice for now.
|
||||
|
@ -122,6 +122,10 @@ cxx_expand_expr (exp, target, tmode, modifier)
|
||||
/* We don't need to generate any code for an empty class. */
|
||||
return const0_rtx;
|
||||
|
||||
case BASELINK:
|
||||
return expand_expr (BASELINK_FUNCTIONS (exp), target, tmode,
|
||||
modifier);
|
||||
|
||||
default:
|
||||
return c_expand_expr (exp, target, tmode, modifier);
|
||||
}
|
||||
|
@ -913,18 +913,31 @@ member_init_ok_or_else (field, type, member_name)
|
||||
{
|
||||
if (field == error_mark_node)
|
||||
return 0;
|
||||
if (field == NULL_TREE || initializing_context (field) != type)
|
||||
if (!field)
|
||||
{
|
||||
error ("class `%T' does not have any field named `%D'", type,
|
||||
member_name);
|
||||
return 0;
|
||||
}
|
||||
if (TREE_CODE (field) == VAR_DECL)
|
||||
{
|
||||
error ("`%#D' is a static data member; it can only be "
|
||||
"initialized at its definition",
|
||||
field);
|
||||
return 0;
|
||||
}
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
{
|
||||
error ("`%#D' is not a non-static data member of `%T'",
|
||||
field, type);
|
||||
return 0;
|
||||
}
|
||||
if (initializing_context (field) != type)
|
||||
{
|
||||
error ("class `%T' does not have any field named `%D'", type,
|
||||
member_name);
|
||||
return 0;
|
||||
}
|
||||
if (TREE_STATIC (field))
|
||||
{
|
||||
error ("field `%#D' is static; the only point of initialization is its definition",
|
||||
field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1601,7 +1614,7 @@ build_offset_ref (type, name)
|
||||
|
||||
decl = maybe_dummy_object (type, &basebinfo);
|
||||
|
||||
if (BASELINK_P (name))
|
||||
if (BASELINK_P (name) || DECL_P (name))
|
||||
member = name;
|
||||
else
|
||||
{
|
||||
|
248
gcc/cp/lex.c
248
gcc/cp/lex.c
@ -32,7 +32,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "cp-tree.h"
|
||||
#include "cpplib.h"
|
||||
#include "lex.h"
|
||||
#include "parse.h"
|
||||
#include "flags.h"
|
||||
#include "c-pragma.h"
|
||||
#include "toplev.h"
|
||||
@ -47,8 +46,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
extern void yyprint PARAMS ((FILE *, int, YYSTYPE));
|
||||
|
||||
static int interface_strcmp PARAMS ((const char *));
|
||||
static int *init_cpp_parse PARAMS ((void));
|
||||
static void init_cp_pragma PARAMS ((void));
|
||||
@ -80,8 +77,6 @@ static void copy_lang_type PARAMS ((tree));
|
||||
#include "cpplib.h"
|
||||
|
||||
extern int yychar; /* the lookahead symbol */
|
||||
extern YYSTYPE yylval; /* the semantic value of the */
|
||||
/* lookahead symbol */
|
||||
|
||||
/* the declaration found for the last IDENTIFIER token read in. yylex
|
||||
must look this up to detect typedefs, which get token type
|
||||
@ -153,21 +148,6 @@ tree
|
||||
make_reference_declarator (cv_qualifiers, target)
|
||||
tree cv_qualifiers, target;
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
if (TREE_CODE (target) == ADDR_EXPR)
|
||||
{
|
||||
error ("cannot declare references to references");
|
||||
return target;
|
||||
}
|
||||
if (TREE_CODE (target) == INDIRECT_REF)
|
||||
{
|
||||
error ("cannot declare pointers to references");
|
||||
return target;
|
||||
}
|
||||
if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
|
||||
error ("type name expected before `&'");
|
||||
}
|
||||
target = build_nt (ADDR_EXPR, target);
|
||||
TREE_TYPE (target) = cv_qualifiers;
|
||||
return target;
|
||||
@ -431,134 +411,6 @@ static const struct resword reswords[] =
|
||||
|
||||
};
|
||||
|
||||
/* Table mapping from RID_* constants to yacc token numbers.
|
||||
Unfortunately we have to have entries for all the keywords in all
|
||||
three languages. */
|
||||
const short rid_to_yy[RID_MAX] =
|
||||
{
|
||||
/* RID_STATIC */ SCSPEC,
|
||||
/* RID_UNSIGNED */ TYPESPEC,
|
||||
/* RID_LONG */ TYPESPEC,
|
||||
/* RID_CONST */ CV_QUALIFIER,
|
||||
/* RID_EXTERN */ SCSPEC,
|
||||
/* RID_REGISTER */ SCSPEC,
|
||||
/* RID_TYPEDEF */ SCSPEC,
|
||||
/* RID_SHORT */ TYPESPEC,
|
||||
/* RID_INLINE */ SCSPEC,
|
||||
/* RID_VOLATILE */ CV_QUALIFIER,
|
||||
/* RID_SIGNED */ TYPESPEC,
|
||||
/* RID_AUTO */ SCSPEC,
|
||||
/* RID_RESTRICT */ CV_QUALIFIER,
|
||||
|
||||
/* C extensions. Bounded pointers are not yet in C++ */
|
||||
/* RID_BOUNDED */ 0,
|
||||
/* RID_UNBOUNDED */ 0,
|
||||
/* RID_COMPLEX */ TYPESPEC,
|
||||
/* RID_THREAD */ SCSPEC,
|
||||
|
||||
/* C++ */
|
||||
/* RID_FRIEND */ SCSPEC,
|
||||
/* RID_VIRTUAL */ SCSPEC,
|
||||
/* RID_EXPLICIT */ SCSPEC,
|
||||
/* RID_EXPORT */ EXPORT,
|
||||
/* RID_MUTABLE */ SCSPEC,
|
||||
|
||||
/* ObjC */
|
||||
/* RID_IN */ 0,
|
||||
/* RID_OUT */ 0,
|
||||
/* RID_INOUT */ 0,
|
||||
/* RID_BYCOPY */ 0,
|
||||
/* RID_BYREF */ 0,
|
||||
/* RID_ONEWAY */ 0,
|
||||
|
||||
/* C */
|
||||
/* RID_INT */ TYPESPEC,
|
||||
/* RID_CHAR */ TYPESPEC,
|
||||
/* RID_FLOAT */ TYPESPEC,
|
||||
/* RID_DOUBLE */ TYPESPEC,
|
||||
/* RID_VOID */ TYPESPEC,
|
||||
/* RID_ENUM */ ENUM,
|
||||
/* RID_STRUCT */ AGGR,
|
||||
/* RID_UNION */ AGGR,
|
||||
/* RID_IF */ IF,
|
||||
/* RID_ELSE */ ELSE,
|
||||
/* RID_WHILE */ WHILE,
|
||||
/* RID_DO */ DO,
|
||||
/* RID_FOR */ FOR,
|
||||
/* RID_SWITCH */ SWITCH,
|
||||
/* RID_CASE */ CASE,
|
||||
/* RID_DEFAULT */ DEFAULT,
|
||||
/* RID_BREAK */ BREAK,
|
||||
/* RID_CONTINUE */ CONTINUE,
|
||||
/* RID_RETURN */ RETURN_KEYWORD,
|
||||
/* RID_GOTO */ GOTO,
|
||||
/* RID_SIZEOF */ SIZEOF,
|
||||
|
||||
/* C extensions */
|
||||
/* RID_ASM */ ASM_KEYWORD,
|
||||
/* RID_TYPEOF */ TYPEOF,
|
||||
/* RID_ALIGNOF */ ALIGNOF,
|
||||
/* RID_ATTRIBUTE */ ATTRIBUTE,
|
||||
/* RID_VA_ARG */ VA_ARG,
|
||||
/* RID_EXTENSION */ EXTENSION,
|
||||
/* RID_IMAGPART */ IMAGPART,
|
||||
/* RID_REALPART */ REALPART,
|
||||
/* RID_LABEL */ LABEL,
|
||||
/* RID_PTRBASE */ 0,
|
||||
/* RID_PTREXTENT */ 0,
|
||||
/* RID_PTRVALUE */ 0,
|
||||
/* RID_CHOOSE_EXPR */ 0,
|
||||
/* RID_TYPES_COMPATIBLE_P */ 0,
|
||||
|
||||
/* RID_FUNCTION_NAME */ VAR_FUNC_NAME,
|
||||
/* RID_PRETTY_FUNCTION_NAME */ VAR_FUNC_NAME,
|
||||
/* RID_c99_FUNCTION_NAME */ VAR_FUNC_NAME,
|
||||
|
||||
/* C++ */
|
||||
/* RID_BOOL */ TYPESPEC,
|
||||
/* RID_WCHAR */ TYPESPEC,
|
||||
/* RID_CLASS */ AGGR,
|
||||
/* RID_PUBLIC */ VISSPEC,
|
||||
/* RID_PRIVATE */ VISSPEC,
|
||||
/* RID_PROTECTED */ VISSPEC,
|
||||
/* RID_TEMPLATE */ TEMPLATE,
|
||||
/* RID_NULL */ CONSTANT,
|
||||
/* RID_CATCH */ CATCH,
|
||||
/* RID_DELETE */ DELETE,
|
||||
/* RID_FALSE */ CXX_FALSE,
|
||||
/* RID_NAMESPACE */ NAMESPACE,
|
||||
/* RID_NEW */ NEW,
|
||||
/* RID_OPERATOR */ OPERATOR,
|
||||
/* RID_THIS */ THIS,
|
||||
/* RID_THROW */ THROW,
|
||||
/* RID_TRUE */ CXX_TRUE,
|
||||
/* RID_TRY */ TRY,
|
||||
/* RID_TYPENAME */ TYPENAME_KEYWORD,
|
||||
/* RID_TYPEID */ TYPEID,
|
||||
/* RID_USING */ USING,
|
||||
|
||||
/* casts */
|
||||
/* RID_CONSTCAST */ CONST_CAST,
|
||||
/* RID_DYNCAST */ DYNAMIC_CAST,
|
||||
/* RID_REINTCAST */ REINTERPRET_CAST,
|
||||
/* RID_STATCAST */ STATIC_CAST,
|
||||
|
||||
/* Objective-C */
|
||||
/* RID_ID */ 0,
|
||||
/* RID_AT_ENCODE */ 0,
|
||||
/* RID_AT_END */ 0,
|
||||
/* RID_AT_CLASS */ 0,
|
||||
/* RID_AT_ALIAS */ 0,
|
||||
/* RID_AT_DEFS */ 0,
|
||||
/* RID_AT_PRIVATE */ 0,
|
||||
/* RID_AT_PROTECTED */ 0,
|
||||
/* RID_AT_PUBLIC */ 0,
|
||||
/* RID_AT_PROTOCOL */ 0,
|
||||
/* RID_AT_SELECTOR */ 0,
|
||||
/* RID_AT_INTERFACE */ 0,
|
||||
/* RID_AT_IMPLEMENTATION */ 0
|
||||
};
|
||||
|
||||
void
|
||||
init_reswords ()
|
||||
{
|
||||
@ -609,7 +461,6 @@ cxx_init (filename)
|
||||
input_filename = "<internal>";
|
||||
|
||||
init_reswords ();
|
||||
init_spew ();
|
||||
init_tree ();
|
||||
init_cp_semantics ();
|
||||
init_operators ();
|
||||
@ -655,75 +506,6 @@ cxx_init (filename)
|
||||
return filename;
|
||||
}
|
||||
|
||||
inline void
|
||||
yyprint (file, yychar, yylval)
|
||||
FILE *file;
|
||||
int yychar;
|
||||
YYSTYPE yylval;
|
||||
{
|
||||
tree t;
|
||||
switch (yychar)
|
||||
{
|
||||
case IDENTIFIER:
|
||||
case tTYPENAME:
|
||||
case TYPESPEC:
|
||||
case PTYPENAME:
|
||||
case PFUNCNAME:
|
||||
case IDENTIFIER_DEFN:
|
||||
case TYPENAME_DEFN:
|
||||
case PTYPENAME_DEFN:
|
||||
case SCSPEC:
|
||||
case PRE_PARSED_CLASS_DECL:
|
||||
t = yylval.ttype;
|
||||
if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
|
||||
{
|
||||
fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
|
||||
break;
|
||||
}
|
||||
my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
|
||||
if (IDENTIFIER_POINTER (t))
|
||||
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
|
||||
break;
|
||||
|
||||
case AGGR:
|
||||
if (yylval.ttype == class_type_node)
|
||||
fprintf (file, " `class'");
|
||||
else if (yylval.ttype == record_type_node)
|
||||
fprintf (file, " `struct'");
|
||||
else if (yylval.ttype == union_type_node)
|
||||
fprintf (file, " `union'");
|
||||
else if (yylval.ttype == enum_type_node)
|
||||
fprintf (file, " `enum'");
|
||||
else
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case CONSTANT:
|
||||
t = yylval.ttype;
|
||||
if (TREE_CODE (t) == INTEGER_CST)
|
||||
fprintf (file,
|
||||
#if HOST_BITS_PER_WIDE_INT == 64
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
|
||||
" 0x%x%016x",
|
||||
#else
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
" 0x%lx%016lx",
|
||||
#else
|
||||
" 0x%llx%016llx",
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
|
||||
" 0x%lx%08lx",
|
||||
#else
|
||||
" 0x%x%08x",
|
||||
#endif
|
||||
#endif
|
||||
TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
|
||||
static int *reduce_count;
|
||||
#endif
|
||||
@ -873,36 +655,6 @@ interface_strcmp (s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Heuristic to tell whether the user is missing a semicolon
|
||||
after a struct or enum declaration. Emit an error message
|
||||
if we know the user has blown it. */
|
||||
|
||||
void
|
||||
check_for_missing_semicolon (type)
|
||||
tree type;
|
||||
{
|
||||
if (yychar < 0)
|
||||
yychar = yylex ();
|
||||
|
||||
if ((yychar > 255
|
||||
&& yychar != SCSPEC
|
||||
&& yychar != IDENTIFIER
|
||||
&& yychar != tTYPENAME
|
||||
&& yychar != CV_QUALIFIER
|
||||
&& yychar != SELFNAME)
|
||||
|| yychar == 0 /* EOF */)
|
||||
{
|
||||
if (TYPE_ANONYMOUS_P (type))
|
||||
error ("semicolon missing after %s declaration",
|
||||
TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
|
||||
else
|
||||
error ("semicolon missing after declaration of `%T'", type);
|
||||
shadow_tag (build_tree_list (0, type));
|
||||
}
|
||||
/* Could probably also hack cases where class { ... } f (); appears. */
|
||||
clear_anon_tags ();
|
||||
}
|
||||
|
||||
void
|
||||
note_got_semicolon (type)
|
||||
tree type;
|
||||
|
@ -74,10 +74,6 @@ extern GTY(()) tree lastiddecl;
|
||||
extern int looking_for_typename;
|
||||
extern int looking_for_template;
|
||||
|
||||
/* Tell the lexer where to look for names. */
|
||||
extern GTY(()) tree got_scope;
|
||||
extern GTY(()) tree got_object;
|
||||
|
||||
/* Pending language change.
|
||||
Positive is push count, negative is pop count. */
|
||||
extern int pending_lang_change;
|
||||
|
@ -145,43 +145,8 @@ hack_identifier (tree value, tree name)
|
||||
|
||||
type = TREE_TYPE (value);
|
||||
if (TREE_CODE (value) == FIELD_DECL)
|
||||
{
|
||||
if (current_class_ptr == NULL_TREE)
|
||||
{
|
||||
if (current_function_decl
|
||||
&& DECL_STATIC_FUNCTION_P (current_function_decl))
|
||||
error ("invalid use of member `%D' in static member function",
|
||||
value);
|
||||
else
|
||||
/* We can get here when processing a bad default
|
||||
argument, like:
|
||||
struct S { int a; void f(int i = a); } */
|
||||
error ("invalid use of member `%D'", value);
|
||||
|
||||
return error_mark_node;
|
||||
}
|
||||
TREE_USED (current_class_ptr) = 1;
|
||||
if (processing_template_decl)
|
||||
value = build_min_nt (COMPONENT_REF, current_class_ref, name);
|
||||
else
|
||||
{
|
||||
tree access_type = current_class_type;
|
||||
|
||||
while (!DERIVED_FROM_P (context_for_name_lookup (value),
|
||||
access_type))
|
||||
{
|
||||
access_type = TYPE_CONTEXT (access_type);
|
||||
while (DECL_P (access_type))
|
||||
access_type = DECL_CONTEXT (access_type);
|
||||
}
|
||||
|
||||
enforce_access (access_type, value);
|
||||
value
|
||||
= build_class_member_access_expr (current_class_ref, value,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/false);
|
||||
}
|
||||
}
|
||||
value = finish_non_static_data_member (value,
|
||||
/*qualifying_scope=*/NULL_TREE);
|
||||
else if ((TREE_CODE (value) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_MEMBER_P (value))
|
||||
|| (TREE_CODE (value) == OVERLOAD
|
||||
@ -1013,7 +978,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
|
||||
tree raises = empty_except_spec;
|
||||
bool retref = false;
|
||||
bool has_parm = false;
|
||||
tree name = constructor_name (TYPE_IDENTIFIER (type));
|
||||
tree name = constructor_name (type);
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
|
14825
gcc/cp/parser.c
Normal file
14825
gcc/cp/parser.c
Normal file
File diff suppressed because it is too large
Load Diff
365
gcc/cp/pt.c
365
gcc/cp/pt.c
@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "cp-tree.h"
|
||||
#include "tree-inline.h"
|
||||
#include "decl.h"
|
||||
#include "parse.h"
|
||||
#include "lex.h"
|
||||
#include "output.h"
|
||||
#include "except.h"
|
||||
@ -135,7 +134,6 @@ static tree tsubst_friend_class PARAMS ((tree, tree));
|
||||
static int can_complete_type_without_circularity PARAMS ((tree));
|
||||
static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
|
||||
static int template_decl_level PARAMS ((tree));
|
||||
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
|
||||
static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
|
||||
static tree tsubst_template_arg_vector PARAMS ((tree, tree, tsubst_flags_t));
|
||||
static tree tsubst_template_parms PARAMS ((tree, tree, tsubst_flags_t));
|
||||
@ -167,30 +165,33 @@ static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
|
||||
static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
|
||||
static void copy_default_args_to_explicit_spec PARAMS ((tree));
|
||||
static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
|
||||
static int eq_local_specializations (const void *, const void *);
|
||||
static tree template_for_substitution (tree);
|
||||
|
||||
/* Do any processing required when DECL (a member template declaration
|
||||
using TEMPLATE_PARAMETERS as its innermost parameter list) is
|
||||
finished. Returns the TEMPLATE_DECL corresponding to DECL, unless
|
||||
it is a specialization, in which case the DECL itself is returned. */
|
||||
/* Do any processing required when DECL (a member template
|
||||
declaration) is finished. Returns the TEMPLATE_DECL corresponding
|
||||
to DECL, unless it is a specialization, in which case the DECL
|
||||
itself is returned. */
|
||||
|
||||
tree
|
||||
finish_member_template_decl (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (decl == NULL_TREE || decl == void_type_node)
|
||||
return NULL_TREE;
|
||||
else if (decl == error_mark_node)
|
||||
/* By returning NULL_TREE, the parser will just ignore this
|
||||
declaration. We have already issued the error. */
|
||||
return NULL_TREE;
|
||||
else if (TREE_CODE (decl) == TREE_LIST)
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
my_friendly_assert (DECL_P (decl), 20020812);
|
||||
|
||||
if (TREE_CODE (decl) == TYPE_DECL)
|
||||
{
|
||||
/* Assume that the class is the only declspec. */
|
||||
decl = TREE_VALUE (decl);
|
||||
if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl)
|
||||
&& ! CLASSTYPE_TEMPLATE_SPECIALIZATION (decl))
|
||||
tree type;
|
||||
|
||||
type = TREE_TYPE (decl);
|
||||
if (IS_AGGR_TYPE (type)
|
||||
&& CLASSTYPE_TEMPLATE_INFO (type)
|
||||
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
|
||||
{
|
||||
tree tmpl = CLASSTYPE_TI_TEMPLATE (decl);
|
||||
tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
|
||||
check_member_template (tmpl);
|
||||
return tmpl;
|
||||
}
|
||||
@ -665,15 +666,16 @@ note_template_header (specialization)
|
||||
void
|
||||
begin_explicit_instantiation ()
|
||||
{
|
||||
++processing_explicit_instantiation;
|
||||
my_friendly_assert (!processing_explicit_instantiation, 20020913);
|
||||
processing_explicit_instantiation = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
end_explicit_instantiation ()
|
||||
{
|
||||
my_friendly_assert(processing_explicit_instantiation > 0, 0);
|
||||
--processing_explicit_instantiation;
|
||||
my_friendly_assert(processing_explicit_instantiation, 20020913);
|
||||
processing_explicit_instantiation = false;
|
||||
}
|
||||
|
||||
/* The TYPE is being declared. If it is a template type, that means it
|
||||
@ -683,7 +685,7 @@ void
|
||||
maybe_process_partial_specialization (type)
|
||||
tree type;
|
||||
{
|
||||
if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type))
|
||||
if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
|
||||
{
|
||||
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
|
||||
&& !COMPLETE_TYPE_P (type))
|
||||
@ -743,7 +745,10 @@ static tree
|
||||
retrieve_local_specialization (tmpl)
|
||||
tree tmpl;
|
||||
{
|
||||
return (tree) htab_find (local_specializations, tmpl);
|
||||
tree spec =
|
||||
(tree) htab_find_with_hash (local_specializations, tmpl,
|
||||
htab_hash_pointer (tmpl));
|
||||
return spec ? TREE_PURPOSE (spec) : NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns nonzero iff DECL is a specialization of TMPL. */
|
||||
@ -909,6 +914,16 @@ unregister_specialization (spec, tmpl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compare an entry in the local specializations hash table P1 (which
|
||||
is really a pointer to a TREE_LIST) with P2 (which is really a
|
||||
DECL). */
|
||||
|
||||
static int
|
||||
eq_local_specializations (const void *p1, const void *p2)
|
||||
{
|
||||
return TREE_VALUE ((tree) p1) == (tree) p2;
|
||||
}
|
||||
|
||||
/* Like register_specialization, but for local declarations. We are
|
||||
registering SPEC, an instantiation of TMPL. */
|
||||
|
||||
@ -919,8 +934,9 @@ register_local_specialization (spec, tmpl)
|
||||
{
|
||||
void **slot;
|
||||
|
||||
slot = htab_find_slot (local_specializations, tmpl, INSERT);
|
||||
*slot = spec;
|
||||
slot = htab_find_slot_with_hash (local_specializations, tmpl,
|
||||
htab_hash_pointer (tmpl), INSERT);
|
||||
*slot = build_tree_list (spec, tmpl);
|
||||
}
|
||||
|
||||
/* Print the list of candidate FNS in an error message. */
|
||||
@ -2600,9 +2616,7 @@ push_template_decl_real (decl, is_friend)
|
||||
|
||||
if (!ctx
|
||||
|| TREE_CODE (ctx) == FUNCTION_DECL
|
||||
|| (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM
|
||||
&& TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM
|
||||
&& TYPE_BEING_DEFINED (ctx))
|
||||
|| (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
|
||||
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
|
||||
{
|
||||
if (DECL_LANG_SPECIFIC (decl)
|
||||
@ -3875,7 +3889,7 @@ lookup_template_function (fns, arglist)
|
||||
return the associated TEMPLATE_DECL. Otherwise, the original
|
||||
DECL is returned. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
maybe_get_template_decl_from_type_decl (decl)
|
||||
tree decl;
|
||||
{
|
||||
@ -4427,6 +4441,12 @@ for_each_template_parm_r (tp, walk_subtrees, d)
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPEOF_TYPE:
|
||||
if (for_each_template_parm (TYPE_FIELDS (t), fn, data,
|
||||
pfd->visited))
|
||||
return error_mark_node;
|
||||
break;
|
||||
|
||||
case FUNCTION_DECL:
|
||||
case VAR_DECL:
|
||||
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
|
||||
@ -4435,8 +4455,12 @@ for_each_template_parm_r (tp, walk_subtrees, d)
|
||||
return error_mark_node;
|
||||
/* Fall through. */
|
||||
|
||||
case CONST_DECL:
|
||||
case PARM_DECL:
|
||||
case CONST_DECL:
|
||||
if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
|
||||
&& for_each_template_parm (DECL_INITIAL (t), fn, data,
|
||||
pfd->visited))
|
||||
return error_mark_node;
|
||||
if (DECL_CONTEXT (t)
|
||||
&& for_each_template_parm (DECL_CONTEXT (t), fn, data,
|
||||
pfd->visited))
|
||||
@ -5951,10 +5975,6 @@ tsubst_decl (t, args, type, complain)
|
||||
being called from tsubst_friend_function, and we want
|
||||
only to create a new decl (R) with appropriate types so
|
||||
that we can call determine_specialization. */
|
||||
my_friendly_assert ((TREE_CODE (DECL_TI_TEMPLATE (t))
|
||||
== LOOKUP_EXPR)
|
||||
|| (TREE_CODE (DECL_TI_TEMPLATE (t))
|
||||
== IDENTIFIER_NODE), 0);
|
||||
gen_tmpl = NULL_TREE;
|
||||
}
|
||||
|
||||
@ -7059,13 +7079,17 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
switch (code)
|
||||
{
|
||||
case PARM_DECL:
|
||||
return do_identifier (DECL_NAME (t), 0, NULL_TREE);
|
||||
r = retrieve_local_specialization (t);
|
||||
my_friendly_assert (r != NULL, 20020903);
|
||||
return r;
|
||||
|
||||
case CONST_DECL:
|
||||
{
|
||||
tree enum_type;
|
||||
tree v;
|
||||
|
||||
if (DECL_TEMPLATE_PARM_P (t))
|
||||
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
|
||||
if (!DECL_CONTEXT (t))
|
||||
/* This is a global enumeration constant. */
|
||||
return t;
|
||||
@ -7111,13 +7135,53 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
|
||||
case VAR_DECL:
|
||||
case FUNCTION_DECL:
|
||||
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
|
||||
if ((DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
|
||||
|| local_variable_p (t))
|
||||
t = tsubst (t, args, complain, in_decl);
|
||||
mark_used (t);
|
||||
return t;
|
||||
|
||||
case BASELINK:
|
||||
{
|
||||
tree name;
|
||||
tree qualifying_scope;
|
||||
tree fns;
|
||||
tree template_args;
|
||||
bool template_id_p = false;
|
||||
|
||||
/* A baselink indicates a function from a base class. The
|
||||
BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have
|
||||
non-dependent types; otherwise, the lookup could not have
|
||||
succeeded. However, they may indicate bases of the template
|
||||
class, rather than the instantiated class.
|
||||
|
||||
In addition, lookups that were not ambiguous before may be
|
||||
ambiguous now. Therefore, we perform the lookup again. */
|
||||
qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (t));
|
||||
fns = BASELINK_FUNCTIONS (t);
|
||||
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
|
||||
{
|
||||
template_id_p = true;
|
||||
template_args = TREE_OPERAND (fns, 1);
|
||||
fns = TREE_OPERAND (fns, 0);
|
||||
}
|
||||
name = DECL_NAME (get_first_fn (fns));
|
||||
t = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
|
||||
if (BASELINK_P (t) && template_id_p)
|
||||
BASELINK_FUNCTIONS (t)
|
||||
= build_nt (TEMPLATE_ID_EXPR,
|
||||
BASELINK_FUNCTIONS (t),
|
||||
template_args);
|
||||
return adjust_result_of_qualified_name_lookup (t,
|
||||
qualifying_scope,
|
||||
current_class_type);
|
||||
}
|
||||
|
||||
case TEMPLATE_DECL:
|
||||
if (is_member_template (t))
|
||||
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
|
||||
return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
|
||||
args, complain, in_decl);
|
||||
else if (is_member_template (t))
|
||||
return tsubst (t, args, complain, in_decl);
|
||||
else
|
||||
return t;
|
||||
@ -7168,6 +7232,35 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
(code, tsubst (TREE_TYPE (t), args, complain, in_decl),
|
||||
tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
|
||||
|
||||
case COMPONENT_REF:
|
||||
{
|
||||
tree object;
|
||||
tree name;
|
||||
|
||||
object = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
|
||||
name = TREE_OPERAND (t, 1);
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
name = tsubst_copy (TREE_OPERAND (name, 0), args,
|
||||
complain, in_decl);
|
||||
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
|
||||
}
|
||||
else if (TREE_CODE (name) == SCOPE_REF
|
||||
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
|
||||
{
|
||||
tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
|
||||
complain, in_decl);
|
||||
name = TREE_OPERAND (name, 1);
|
||||
name = tsubst_copy (TREE_OPERAND (name, 0), args,
|
||||
complain, in_decl);
|
||||
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
|
||||
name = build_nt (SCOPE_REF, base, name);
|
||||
}
|
||||
else
|
||||
name = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
|
||||
return build_nt (COMPONENT_REF, object, name);
|
||||
}
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
@ -7198,7 +7291,6 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
case GE_EXPR:
|
||||
case LT_EXPR:
|
||||
case GT_EXPR:
|
||||
case COMPONENT_REF:
|
||||
case ARRAY_REF:
|
||||
case COMPOUND_EXPR:
|
||||
case SCOPE_REF:
|
||||
@ -7213,48 +7305,20 @@ tsubst_copy (t, args, complain, in_decl)
|
||||
tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
|
||||
|
||||
case CALL_EXPR:
|
||||
{
|
||||
tree fn = TREE_OPERAND (t, 0);
|
||||
if (is_overloaded_fn (fn))
|
||||
fn = tsubst_copy (get_first_fn (fn), args, complain, in_decl);
|
||||
else
|
||||
/* Sometimes FN is a LOOKUP_EXPR. */
|
||||
fn = tsubst_copy (fn, args, complain, in_decl);
|
||||
return build_nt
|
||||
(code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, complain,
|
||||
in_decl),
|
||||
NULL_TREE);
|
||||
}
|
||||
return build_nt (code,
|
||||
tsubst_copy (TREE_OPERAND (t, 0), args,
|
||||
complain, in_decl),
|
||||
tsubst_copy (TREE_OPERAND (t, 1), args, complain,
|
||||
in_decl),
|
||||
NULL_TREE);
|
||||
|
||||
case METHOD_CALL_EXPR:
|
||||
{
|
||||
tree name = TREE_OPERAND (t, 0);
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
name = tsubst_copy (TREE_OPERAND (name, 0), args,
|
||||
complain, in_decl);
|
||||
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
|
||||
}
|
||||
else if (TREE_CODE (name) == SCOPE_REF
|
||||
&& TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
|
||||
{
|
||||
tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
|
||||
complain, in_decl);
|
||||
name = TREE_OPERAND (TREE_OPERAND (name, 1), 0);
|
||||
if (TREE_CODE (name) == TYPE_DECL)
|
||||
name = TREE_TYPE (name);
|
||||
name = tsubst_copy (name, args, complain, in_decl);
|
||||
name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
|
||||
name = build_nt (SCOPE_REF, base, name);
|
||||
}
|
||||
else
|
||||
name = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
|
||||
return build_nt
|
||||
(code, name, tsubst_copy (TREE_OPERAND (t, 1), args,
|
||||
complain, in_decl),
|
||||
tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),
|
||||
NULL_TREE);
|
||||
}
|
||||
return build_nt
|
||||
(code,
|
||||
tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
|
||||
tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
|
||||
tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),
|
||||
NULL_TREE);
|
||||
|
||||
case STMT_EXPR:
|
||||
/* This processing should really occur in tsubst_expr, However,
|
||||
@ -7465,7 +7529,10 @@ tsubst_expr (t, args, complain, in_decl)
|
||||
tree name = DECL_NAME (decl);
|
||||
|
||||
scope = tsubst_expr (scope, args, complain, in_decl);
|
||||
do_local_using_decl (build_nt (SCOPE_REF, scope, name));
|
||||
do_local_using_decl (lookup_qualified_name (scope,
|
||||
name,
|
||||
/*is_type_p=*/0,
|
||||
/*flags=*/0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -9123,6 +9190,8 @@ unify (tparms, targs, parm, arg, strict)
|
||||
strict);
|
||||
|
||||
case CONST_DECL:
|
||||
if (DECL_TEMPLATE_PARM_P (parm))
|
||||
return unify (tparms, targs, DECL_INITIAL (parm), arg, strict);
|
||||
if (arg != decl_constant_value (parm))
|
||||
return 1;
|
||||
return 0;
|
||||
@ -9915,7 +9984,7 @@ regenerate_decl_from_template (decl, tmpl)
|
||||
/* Make sure that we can see identifiers, and compute access
|
||||
correctly, for the class members used in the declaration of
|
||||
this static variable or function. */
|
||||
pushclass (DECL_CONTEXT (decl), 2);
|
||||
push_nested_class (DECL_CONTEXT (decl), 2);
|
||||
|
||||
/* Do the substitution to get the new declaration. */
|
||||
new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
|
||||
@ -9939,7 +10008,7 @@ regenerate_decl_from_template (decl, tmpl)
|
||||
|
||||
/* Pop the class context we pushed above. */
|
||||
if (DECL_CLASS_SCOPE_P (decl))
|
||||
popclass ();
|
||||
pop_nested_class ();
|
||||
|
||||
/* The immediate parent of the new template is still whatever it was
|
||||
before, even though tsubst sets DECL_TI_TEMPLATE up as the most
|
||||
@ -9960,6 +10029,65 @@ regenerate_decl_from_template (decl, tmpl)
|
||||
register_specialization (decl, gen_tmpl, args);
|
||||
}
|
||||
|
||||
/* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be
|
||||
substituted to get DECL. */
|
||||
|
||||
static tree
|
||||
template_for_substitution (tree decl)
|
||||
{
|
||||
tree tmpl = DECL_TI_TEMPLATE (decl);
|
||||
|
||||
/* Set TMPL to the template whose DECL_TEMPLATE_RESULT is the pattern
|
||||
for the instantiation. This is not always the most general
|
||||
template. Consider, for example:
|
||||
|
||||
template <class T>
|
||||
struct S { template <class U> void f();
|
||||
template <> void f<int>(); };
|
||||
|
||||
and an instantiation of S<double>::f<int>. We want TD to be the
|
||||
specialization S<T>::f<int>, not the more general S<T>::f<U>. */
|
||||
while (/* An instantiation cannot have a definition, so we need a
|
||||
more general template. */
|
||||
DECL_TEMPLATE_INSTANTIATION (tmpl)
|
||||
/* We must also deal with friend templates. Given:
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> friend void f() {};
|
||||
};
|
||||
|
||||
S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
|
||||
so far as the language is concerned, but that's still
|
||||
where we get the pattern for the instantiation from. On
|
||||
other hand, if the definition comes outside the class, say:
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> friend void f();
|
||||
};
|
||||
template <class U> friend void f() {}
|
||||
|
||||
we don't need to look any further. That's what the check for
|
||||
DECL_INITIAL is for. */
|
||||
|| (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (tmpl)
|
||||
&& !DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl))))
|
||||
{
|
||||
/* The present template, TD, should not be a definition. If it
|
||||
were a definition, we should be using it! Note that we
|
||||
cannot restructure the loop to just keep going until we find
|
||||
a template with a definition, since that might go too far if
|
||||
a specialization was declared, but not defined. */
|
||||
my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
|
||||
&& !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))),
|
||||
0);
|
||||
|
||||
/* Fetch the more general template. */
|
||||
tmpl = DECL_TI_TEMPLATE (tmpl);
|
||||
}
|
||||
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
/* Produce the definition of D, a _DECL generated from a template. If
|
||||
DEFER_OK is nonzero, then we don't have to actually do the
|
||||
instantiation now; we just have to do it sometime. */
|
||||
@ -10017,54 +10145,8 @@ instantiate_decl (d, defer_ok)
|
||||
timevar_push (TV_PARSE);
|
||||
|
||||
/* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
|
||||
for the instantiation. This is not always the most general
|
||||
template. Consider, for example:
|
||||
|
||||
template <class T>
|
||||
struct S { template <class U> void f();
|
||||
template <> void f<int>(); };
|
||||
|
||||
and an instantiation of S<double>::f<int>. We want TD to be the
|
||||
specialization S<T>::f<int>, not the more general S<T>::f<U>. */
|
||||
td = tmpl;
|
||||
while (/* An instantiation cannot have a definition, so we need a
|
||||
more general template. */
|
||||
DECL_TEMPLATE_INSTANTIATION (td)
|
||||
/* We must also deal with friend templates. Given:
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> friend void f() {};
|
||||
};
|
||||
|
||||
S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
|
||||
so far as the language is concerned, but that's still
|
||||
where we get the pattern for the instantiation from. On
|
||||
other hand, if the definition comes outside the class, say:
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> friend void f();
|
||||
};
|
||||
template <class U> friend void f() {}
|
||||
|
||||
we don't need to look any further. That's what the check for
|
||||
DECL_INITIAL is for. */
|
||||
|| (TREE_CODE (d) == FUNCTION_DECL
|
||||
&& DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td)
|
||||
&& !DECL_INITIAL (DECL_TEMPLATE_RESULT (td))))
|
||||
{
|
||||
/* The present template, TD, should not be a definition. If it
|
||||
were a definition, we should be using it! Note that we
|
||||
cannot restructure the loop to just keep going until we find
|
||||
a template with a definition, since that might go too far if
|
||||
a specialization was declared, but not defined. */
|
||||
my_friendly_assert (!(TREE_CODE (d) == VAR_DECL
|
||||
&& !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (td))),
|
||||
0);
|
||||
|
||||
/* Fetch the more general template. */
|
||||
td = DECL_TI_TEMPLATE (td);
|
||||
}
|
||||
|
||||
for the instantiation. */
|
||||
td = template_for_substitution (d);
|
||||
code_pattern = DECL_TEMPLATE_RESULT (td);
|
||||
|
||||
/* In the case of a friend template whose definition is provided
|
||||
@ -10223,6 +10305,9 @@ instantiate_decl (d, defer_ok)
|
||||
else if (TREE_CODE (d) == FUNCTION_DECL)
|
||||
{
|
||||
htab_t saved_local_specializations;
|
||||
tree subst_decl;
|
||||
tree tmpl_parm;
|
||||
tree spec_parm;
|
||||
|
||||
/* Save away the current list, in case we are instantiating one
|
||||
template from within the body of another. */
|
||||
@ -10230,13 +10315,31 @@ instantiate_decl (d, defer_ok)
|
||||
|
||||
/* Set up the list of local specializations. */
|
||||
local_specializations = htab_create (37,
|
||||
htab_hash_pointer,
|
||||
htab_eq_pointer,
|
||||
NULL,
|
||||
eq_local_specializations,
|
||||
NULL);
|
||||
|
||||
/* Set up context. */
|
||||
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
|
||||
|
||||
/* Create substitution entries for the parameters. */
|
||||
subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d));
|
||||
tmpl_parm = DECL_ARGUMENTS (subst_decl);
|
||||
spec_parm = DECL_ARGUMENTS (d);
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (d))
|
||||
{
|
||||
register_local_specialization (spec_parm, tmpl_parm);
|
||||
spec_parm = skip_artificial_parms_for (d, spec_parm);
|
||||
tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm);
|
||||
}
|
||||
while (tmpl_parm)
|
||||
{
|
||||
register_local_specialization (spec_parm, tmpl_parm);
|
||||
tmpl_parm = TREE_CHAIN (tmpl_parm);
|
||||
spec_parm = TREE_CHAIN (spec_parm);
|
||||
}
|
||||
my_friendly_assert (!spec_parm, 20020813);
|
||||
|
||||
/* Substitute into the body of the function. */
|
||||
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
|
||||
tf_error | tf_warning, tmpl);
|
||||
|
@ -110,14 +110,17 @@ static int doing_runtime = 0;
|
||||
void
|
||||
init_rtti_processing ()
|
||||
{
|
||||
tree const_type_info_type;
|
||||
|
||||
push_namespace (std_identifier);
|
||||
type_info_type_node
|
||||
= xref_tag (class_type, get_identifier ("type_info"),
|
||||
/*attributes=*/NULL_TREE, 1);
|
||||
pop_namespace ();
|
||||
type_info_ptr_type =
|
||||
build_pointer_type
|
||||
(build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
|
||||
const_type_info_type = build_qualified_type (type_info_type_node,
|
||||
TYPE_QUAL_CONST);
|
||||
type_info_ptr_type = build_pointer_type (const_type_info_type);
|
||||
type_info_ref_type = build_reference_type (const_type_info_type);
|
||||
|
||||
create_tinfo_types ();
|
||||
}
|
||||
@ -263,7 +266,7 @@ build_typeid (exp)
|
||||
return error_mark_node;
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (TYPEID_EXPR, exp);
|
||||
return build_min (TYPEID_EXPR, type_info_ref_type, exp);
|
||||
|
||||
if (TREE_CODE (exp) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
|
||||
@ -394,7 +397,7 @@ get_typeid (type)
|
||||
return error_mark_node;
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (TYPEID_EXPR, type);
|
||||
return build_min (TYPEID_EXPR, type_info_ref_type, type);
|
||||
|
||||
/* If the type of the type-id is a reference type, the result of the
|
||||
typeid expression refers to a type_info object representing the
|
||||
|
@ -1035,7 +1035,7 @@ accessible_p (type, decl)
|
||||
int protected_ok = 0;
|
||||
|
||||
/* If we're not checking access, everything is accessible. */
|
||||
if (!flag_access_control)
|
||||
if (!scope_chain->check_access)
|
||||
return 1;
|
||||
|
||||
/* If this declaration is in a block or namespace scope, there's no
|
||||
@ -1674,11 +1674,11 @@ lookup_fnfields_1 (type, name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* DECL is the result of a qualified name lookup. QUALIFYING_CLASS
|
||||
was the class used to qualify the name. CONTEXT_CLASS is the class
|
||||
corresponding to the object in which DECL will be used. Return a
|
||||
possibly modified version of DECL that takes into account the
|
||||
CONTEXT_CLASS.
|
||||
/* DECL is the result of a qualified name lookup. QUALIFYING_SCOPE is
|
||||
the class or namespace used to qualify the name. CONTEXT_CLASS is
|
||||
the class corresponding to the object in which DECL will be used.
|
||||
Return a possibly modified version of DECL that takes into account
|
||||
the CONTEXT_CLASS.
|
||||
|
||||
In particular, consider an expression like `B::m' in the context of
|
||||
a derived class `D'. If `B::m' has been resolved to a BASELINK,
|
||||
@ -1687,22 +1687,22 @@ lookup_fnfields_1 (type, name)
|
||||
|
||||
tree
|
||||
adjust_result_of_qualified_name_lookup (tree decl,
|
||||
tree qualifying_class,
|
||||
tree qualifying_scope,
|
||||
tree context_class)
|
||||
{
|
||||
my_friendly_assert (CLASS_TYPE_P (qualifying_class), 20020808);
|
||||
my_friendly_assert (CLASS_TYPE_P (context_class), 20020808);
|
||||
|
||||
if (BASELINK_P (decl)
|
||||
&& DERIVED_FROM_P (qualifying_class, context_class))
|
||||
if (context_class && CLASS_TYPE_P (qualifying_scope)
|
||||
&& DERIVED_FROM_P (qualifying_scope, context_class)
|
||||
&& BASELINK_P (decl))
|
||||
{
|
||||
tree base;
|
||||
|
||||
/* Look for the QUALIFYING_CLASS as a base of the
|
||||
CONTEXT_CLASS. If QUALIFYING_CLASS is ambiguous, we cannot
|
||||
my_friendly_assert (CLASS_TYPE_P (context_class), 20020808);
|
||||
|
||||
/* Look for the QUALIFYING_SCOPE as a base of the
|
||||
CONTEXT_CLASS. If QUALIFYING_SCOPE is ambiguous, we cannot
|
||||
be sure yet than an error has occurred; perhaps the function
|
||||
chosen by overload resolution will be static. */
|
||||
base = lookup_base (context_class, qualifying_class,
|
||||
base = lookup_base (context_class, qualifying_scope,
|
||||
ba_ignore | ba_quiet, NULL);
|
||||
if (base)
|
||||
{
|
||||
|
@ -947,9 +947,9 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
|
||||
&allows_reg,
|
||||
&is_inout))
|
||||
{
|
||||
/* By marking the type as erroneous, we will not try to
|
||||
process this operand again in expand_asm_operands. */
|
||||
TREE_TYPE (operand) = error_mark_node;
|
||||
/* By marking this operand as erroneous, we will not try
|
||||
to process this operand again in expand_asm_operands. */
|
||||
TREE_VALUE (t) = error_mark_node;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -972,12 +972,12 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
|
||||
|
||||
/* Finish a label with the indicated NAME. */
|
||||
|
||||
void
|
||||
tree
|
||||
finish_label_stmt (name)
|
||||
tree name;
|
||||
{
|
||||
tree decl = define_label (input_filename, lineno, name);
|
||||
add_stmt (build_stmt (LABEL_STMT, decl));
|
||||
return add_stmt (build_stmt (LABEL_STMT, decl));
|
||||
}
|
||||
|
||||
/* Finish a series of declarations for local labels. G++ allows users
|
||||
@ -1146,6 +1146,58 @@ finish_parenthesized_expr (expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Finish a reference to a non-static data member (DECL) that is not
|
||||
preceded by `.' or `->'. */
|
||||
|
||||
tree
|
||||
finish_non_static_data_member (tree decl, tree qualifying_scope)
|
||||
{
|
||||
my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
|
||||
|
||||
if (current_class_ptr == NULL_TREE)
|
||||
{
|
||||
if (current_function_decl
|
||||
&& DECL_STATIC_FUNCTION_P (current_function_decl))
|
||||
cp_error_at ("invalid use of member `%D' in static member function",
|
||||
decl);
|
||||
else
|
||||
cp_error_at ("invalid use of non-static data member `%D'", decl);
|
||||
error ("from this location");
|
||||
|
||||
return error_mark_node;
|
||||
}
|
||||
TREE_USED (current_class_ptr) = 1;
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (COMPONENT_REF, current_class_ref, DECL_NAME (decl));
|
||||
else
|
||||
{
|
||||
tree access_type = current_class_type;
|
||||
tree object = current_class_ref;
|
||||
|
||||
while (!DERIVED_FROM_P (context_for_name_lookup (decl), access_type))
|
||||
{
|
||||
access_type = TYPE_CONTEXT (access_type);
|
||||
while (DECL_P (access_type))
|
||||
access_type = DECL_CONTEXT (access_type);
|
||||
}
|
||||
|
||||
enforce_access (access_type, decl);
|
||||
|
||||
/* If the data member was named `C::M', convert `*this' to `C'
|
||||
first. */
|
||||
if (qualifying_scope)
|
||||
{
|
||||
tree binfo = NULL_TREE;
|
||||
object = build_scoped_ref (object, qualifying_scope,
|
||||
&binfo);
|
||||
}
|
||||
|
||||
return build_class_member_access_expr (object, decl,
|
||||
/*access_path=*/NULL_TREE,
|
||||
/*preserve_reference=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin a statement-expression. The value returned must be passed to
|
||||
finish_stmt_expr. */
|
||||
|
||||
@ -1251,6 +1303,26 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
|
||||
my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
|
||||
20020712);
|
||||
|
||||
/* A reference to a member function will appear as an overloaded
|
||||
function (rather than a BASELINK) if an unqualified name was used
|
||||
to refer to it. */
|
||||
if (!BASELINK_P (fn) && is_overloaded_fn (fn))
|
||||
{
|
||||
tree f;
|
||||
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
f = get_first_fn (TREE_OPERAND (fn, 0));
|
||||
else
|
||||
f = get_first_fn (fn);
|
||||
if (DECL_FUNCTION_MEMBER_P (f))
|
||||
{
|
||||
tree type = currently_open_derived_class (DECL_CONTEXT (f));
|
||||
fn = build_baselink (TYPE_BINFO (type),
|
||||
TYPE_BINFO (type),
|
||||
fn, /*optype=*/NULL_TREE);
|
||||
}
|
||||
}
|
||||
|
||||
if (BASELINK_P (fn))
|
||||
{
|
||||
tree object;
|
||||
@ -1296,6 +1368,20 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
|
||||
else if (is_overloaded_fn (fn))
|
||||
/* A call to a namespace-scope function. */
|
||||
return build_new_function_call (fn, args);
|
||||
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
|
||||
{
|
||||
tree result;
|
||||
|
||||
if (args)
|
||||
error ("arguments to destructor are not allowed");
|
||||
/* Mark the pseudo-destructor call as having side-effects so
|
||||
that we do not issue warnings about its use. */
|
||||
result = build1 (NOP_EXPR,
|
||||
void_type_node,
|
||||
TREE_OPERAND (fn, 0));
|
||||
TREE_SIDE_EFFECTS (result) = 1;
|
||||
return result;
|
||||
}
|
||||
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
|
||||
{
|
||||
/* If the "function" is really an object of class type, it might
|
||||
@ -1386,6 +1472,11 @@ finish_object_call_expr (fn, object, args)
|
||||
}
|
||||
}
|
||||
|
||||
if (processing_template_decl)
|
||||
return build_nt (CALL_EXPR,
|
||||
build_nt (COMPONENT_REF, object, fn),
|
||||
args);
|
||||
|
||||
if (name_p (fn))
|
||||
return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
|
||||
else
|
||||
@ -1405,29 +1496,38 @@ finish_qualified_object_call_expr (fn, object, args)
|
||||
TREE_OPERAND (fn, 1), args);
|
||||
}
|
||||
|
||||
/* Finish a pseudo-destructor call expression of OBJECT, with SCOPE
|
||||
being the scope, if any, of DESTRUCTOR. Returns an expression for
|
||||
the call. */
|
||||
/* Finish a pseudo-destructor expression. If SCOPE is NULL, the
|
||||
expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
|
||||
the TYPE for the type given. If SCOPE is non-NULL, the expression
|
||||
was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
|
||||
|
||||
tree
|
||||
finish_pseudo_destructor_call_expr (object, scope, destructor)
|
||||
finish_pseudo_destructor_expr (object, scope, destructor)
|
||||
tree object;
|
||||
tree scope;
|
||||
tree destructor;
|
||||
{
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (PSEUDO_DTOR_EXPR, object, scope, destructor);
|
||||
if (destructor == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (scope && scope != destructor)
|
||||
error ("destructor specifier `%T::~%T()' must have matching names",
|
||||
scope, destructor);
|
||||
my_friendly_assert (TYPE_P (destructor), 20010905);
|
||||
|
||||
if ((scope == NULL_TREE || IDENTIFIER_GLOBAL_VALUE (destructor))
|
||||
&& (TREE_CODE (TREE_TYPE (object)) !=
|
||||
TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (destructor)))))
|
||||
error ("`%E' is not of type `%T'", object, destructor);
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
if (scope == error_mark_node)
|
||||
{
|
||||
error ("invalid qualifying scope in pseudo-destructor name");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (!same_type_p (TREE_TYPE (object), destructor))
|
||||
{
|
||||
error ("`%E' is not of type `%T'", object, destructor);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
return cp_convert (void_type_node, object);
|
||||
return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
|
||||
}
|
||||
|
||||
/* Finish an expression of the form CODE EXPR. */
|
||||
@ -1464,6 +1564,40 @@ finish_id_expr (expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Finish a compound-literal expression. TYPE is the type to which
|
||||
the INITIALIZER_LIST is being cast. */
|
||||
|
||||
tree
|
||||
finish_compound_literal (type, initializer_list)
|
||||
tree type;
|
||||
tree initializer_list;
|
||||
{
|
||||
tree compound_literal;
|
||||
|
||||
/* Build a CONSTRUCTOR for the INITIALIZER_LIST. */
|
||||
compound_literal = build_nt (CONSTRUCTOR, NULL_TREE,
|
||||
initializer_list);
|
||||
/* Mark it as a compound-literal. */
|
||||
TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
|
||||
if (processing_template_decl)
|
||||
TREE_TYPE (compound_literal) = type;
|
||||
else
|
||||
{
|
||||
/* Check the initialization. */
|
||||
compound_literal = digest_init (type, compound_literal, NULL);
|
||||
/* If the TYPE was an array type with an unknown bound, then we can
|
||||
figure out the dimension now. For example, something like:
|
||||
|
||||
`(int []) { 2, 3 }'
|
||||
|
||||
implies that the array has two elements. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
|
||||
complete_array_type (type, compound_literal, 1);
|
||||
}
|
||||
|
||||
return compound_literal;
|
||||
}
|
||||
|
||||
/* Return the declaration for the function-name variable indicated by
|
||||
ID. */
|
||||
|
||||
@ -1922,26 +2056,12 @@ finish_class_definition (t, attributes, semi, pop_scope_p)
|
||||
note_got_semicolon (t);
|
||||
}
|
||||
|
||||
if (! semi)
|
||||
check_for_missing_semicolon (t);
|
||||
if (pop_scope_p)
|
||||
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
|
||||
if (current_scope () == current_function_decl)
|
||||
do_pending_defargs ();
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Finish processing the default argument expressions cached during
|
||||
the processing of a class definition. */
|
||||
|
||||
void
|
||||
begin_inline_definitions ()
|
||||
{
|
||||
if (current_scope () == current_function_decl)
|
||||
do_pending_inlines ();
|
||||
}
|
||||
|
||||
/* Finish processing the declaration of a member class template
|
||||
TYPES whose template parameters are given by PARMS. */
|
||||
|
||||
@ -2124,9 +2244,6 @@ tree
|
||||
finish_sizeof (t)
|
||||
tree t;
|
||||
{
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (SIZEOF_EXPR, t);
|
||||
|
||||
return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
|
||||
}
|
||||
|
||||
@ -2138,7 +2255,7 @@ finish_alignof (t)
|
||||
tree t;
|
||||
{
|
||||
if (processing_template_decl)
|
||||
return build_min_nt (ALIGNOF_EXPR, t);
|
||||
return build_min (ALIGNOF_EXPR, size_type_node, t);
|
||||
|
||||
return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "cpplib.h"
|
||||
#include "c-pragma.h"
|
||||
#include "lex.h"
|
||||
#include "parse.h"
|
||||
#include "flags.h"
|
||||
#include "obstack.h"
|
||||
#include "toplev.h"
|
||||
|
@ -1034,20 +1034,6 @@ really_overloaded_fn (x)
|
||||
|| TREE_CODE (x) == TEMPLATE_ID_EXPR);
|
||||
}
|
||||
|
||||
/* Return the OVERLOAD or FUNCTION_DECL inside FNS. FNS can be an
|
||||
OVERLOAD, FUNCTION_DECL, TEMPLATE_ID_EXPR, or baselink. */
|
||||
|
||||
tree
|
||||
get_overloaded_fn (fns)
|
||||
tree fns;
|
||||
{
|
||||
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
|
||||
fns = TREE_OPERAND (fns, 0);
|
||||
if (BASELINK_P (fns))
|
||||
fns = BASELINK_FUNCTIONS (fns);
|
||||
return fns;
|
||||
}
|
||||
|
||||
tree
|
||||
get_first_fn (from)
|
||||
tree from;
|
||||
|
108
gcc/cp/typeck.c
108
gcc/cp/typeck.c
@ -66,6 +66,7 @@ static void casts_away_constness_r PARAMS ((tree *, tree *));
|
||||
static int casts_away_constness PARAMS ((tree, tree));
|
||||
static void maybe_warn_about_returning_address_of_local PARAMS ((tree));
|
||||
static tree strip_all_pointer_quals PARAMS ((tree));
|
||||
static tree lookup_destructor (tree, tree, tree);
|
||||
|
||||
/* Return the target type of TYPE, which means return T for:
|
||||
T*, T&, T[], T (...), and otherwise, just T. */
|
||||
@ -1858,6 +1859,9 @@ build_class_member_access_expr (tree object, tree member,
|
||||
if (object == error_mark_node || member == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (member) == PSEUDO_DTOR_EXPR)
|
||||
return member;
|
||||
|
||||
my_friendly_assert (DECL_P (member) || BASELINK_P (member),
|
||||
20020801);
|
||||
|
||||
@ -1988,7 +1992,14 @@ build_class_member_access_expr (tree object, tree member,
|
||||
anonymous union. Generate a reference to the anonymous union
|
||||
itself, and recur to find MEMBER. */
|
||||
if (ANON_AGGR_TYPE_P (DECL_CONTEXT (member))
|
||||
&& !same_type_p (object_type, DECL_CONTEXT (member)))
|
||||
/* When this code is called from build_field_call, the
|
||||
object already has the type of the anonymous union.
|
||||
That is because the COMPONENT_REF was already
|
||||
constructed, and was then disassembled before calling
|
||||
build_field_call. After the function-call code is
|
||||
cleaned up, this waste can be eliminated. */
|
||||
&& (!same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (object), DECL_CONTEXT (member))))
|
||||
{
|
||||
tree anonymous_union;
|
||||
|
||||
@ -2030,6 +2041,7 @@ build_class_member_access_expr (tree object, tree member,
|
||||
{
|
||||
/* The member is a (possibly overloaded) member function. */
|
||||
tree functions;
|
||||
tree type;
|
||||
|
||||
/* If the MEMBER is exactly one static member function, then we
|
||||
know the type of the expression. Otherwise, we must wait
|
||||
@ -2037,19 +2049,12 @@ build_class_member_access_expr (tree object, tree member,
|
||||
functions = BASELINK_FUNCTIONS (member);
|
||||
if (TREE_CODE (functions) == FUNCTION_DECL
|
||||
&& DECL_STATIC_FUNCTION_P (functions))
|
||||
{
|
||||
/* A static member function. */
|
||||
result = functions;
|
||||
mark_used (result);
|
||||
/* If OBJECT has side-effects, they are supposed to occur. */
|
||||
if (TREE_SIDE_EFFECTS (object))
|
||||
result = build (COMPOUND_EXPR, TREE_TYPE (result),
|
||||
object, result);
|
||||
}
|
||||
type = TREE_TYPE (functions);
|
||||
else
|
||||
/* Note that we do not convert OBJECT to the BASELINK_BINFO
|
||||
base. That will happen when the function is called. */
|
||||
result = build (COMPONENT_REF, unknown_type_node, object, member);
|
||||
type = unknown_type_node;
|
||||
/* Note that we do not convert OBJECT to the BASELINK_BINFO
|
||||
base. That will happen when the function is called. */
|
||||
result = build (COMPONENT_REF, type, object, member);
|
||||
}
|
||||
else if (TREE_CODE (member) == CONST_DECL)
|
||||
{
|
||||
@ -2076,6 +2081,34 @@ build_class_member_access_expr (tree object, tree member,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return the destructor denoted by OBJECT.SCOPE::~DTOR_NAME, or, if
|
||||
SCOPE is NULL, by OBJECT.~DTOR_NAME. */
|
||||
|
||||
static tree
|
||||
lookup_destructor (tree object, tree scope, tree dtor_name)
|
||||
{
|
||||
tree object_type = TREE_TYPE (object);
|
||||
tree dtor_type = TREE_OPERAND (dtor_name, 0);
|
||||
|
||||
if (scope && !check_dtor_name (scope, dtor_name))
|
||||
{
|
||||
error ("qualified type `%T' does not match destructor name `~%T'",
|
||||
scope, dtor_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (!same_type_p (dtor_type, TYPE_MAIN_VARIANT (object_type)))
|
||||
{
|
||||
error ("destructor name `%T' does not match type `%T' of expression",
|
||||
dtor_type, object_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (!TYPE_HAS_DESTRUCTOR (object_type))
|
||||
return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
|
||||
dtor_type);
|
||||
return lookup_member (object_type, complete_dtor_identifier,
|
||||
/*protect=*/1, /*want_type=*/0);
|
||||
}
|
||||
|
||||
/* This function is called by the parser to process a class member
|
||||
access expression of the form OBJECT.NAME. NAME is a node used by
|
||||
the parser to represent a name; it is not yet a DECL. It may,
|
||||
@ -2171,33 +2204,24 @@ finish_class_member_access_expr (tree object, tree name)
|
||||
if (!access_path || access_path == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Look up the member. */
|
||||
member = lookup_member (access_path, name, /*protect=*/1,
|
||||
/*want_type=*/0);
|
||||
if (member == NULL_TREE)
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
member = lookup_destructor (object, scope, name);
|
||||
else
|
||||
{
|
||||
error ("'%D' has no member named '%E'", object_type, name);
|
||||
return error_mark_node;
|
||||
/* Look up the member. */
|
||||
member = lookup_member (access_path, name, /*protect=*/1,
|
||||
/*want_type=*/0);
|
||||
if (member == NULL_TREE)
|
||||
{
|
||||
error ("'%D' has no member named '%E'", object_type, name);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (member == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (member == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
/* A destructor. */
|
||||
if (TYPE_IDENTIFIER (object_type) != TREE_OPERAND (name, 0))
|
||||
{
|
||||
error ("destructor specifier `%T::~%T' must have matching names",
|
||||
object_type, TREE_OPERAND (name, 0));
|
||||
return error_mark_node;
|
||||
}
|
||||
if (! TYPE_HAS_DESTRUCTOR (object_type))
|
||||
{
|
||||
error ("type `%T' has no destructor", object_type);
|
||||
return error_mark_node;
|
||||
}
|
||||
member = CLASSTYPE_DESTRUCTORS (object_type);
|
||||
}
|
||||
member = lookup_destructor (object, /*scope=*/NULL_TREE, name);
|
||||
else if (TREE_CODE (name) == IDENTIFIER_NODE)
|
||||
{
|
||||
/* An unqualified name. */
|
||||
@ -2238,6 +2262,9 @@ finish_class_member_access_expr (tree object, tree name)
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_DEPRECATED (member))
|
||||
warn_deprecated_use (member);
|
||||
|
||||
return build_class_member_access_expr (object, member, access_path,
|
||||
/*preserve_reference=*/false);
|
||||
}
|
||||
@ -2907,7 +2934,8 @@ convert_arguments (typelist, values, fndecl, flags)
|
||||
if (typetail != 0 && typetail != void_list_node)
|
||||
{
|
||||
/* See if there are default arguments that can be used */
|
||||
if (TREE_PURPOSE (typetail))
|
||||
if (TREE_PURPOSE (typetail)
|
||||
&& TREE_CODE (TREE_PURPOSE (typetail)) != DEFAULT_ARG)
|
||||
{
|
||||
for (; typetail != void_list_node; ++i)
|
||||
{
|
||||
@ -4233,7 +4261,7 @@ build_unary_op (code, xarg, noconvert)
|
||||
if (current_class_type
|
||||
&& TREE_OPERAND (arg, 0) == current_class_ref)
|
||||
/* An expression like &memfn. */
|
||||
pedwarn ("ISO C++ forbids taking the address of an unqualified non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
|
||||
pedwarn ("ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
|
||||
else
|
||||
pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'", base, name);
|
||||
}
|
||||
@ -4287,6 +4315,10 @@ build_unary_op (code, xarg, noconvert)
|
||||
{
|
||||
tree addr;
|
||||
|
||||
if (TREE_CODE (arg) == COMPONENT_REF
|
||||
&& TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
|
||||
arg = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
|
||||
|
||||
if (TREE_CODE (arg) == COMPONENT_REF
|
||||
&& DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user