Commit a723baf1 by Mark Mitchell Committed by Mark Mitchell

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
parent 876200a8
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
*** 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)".
......
......@@ -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"
......@@ -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);
......
......@@ -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,16 +913,29 @@ 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);
member_name);
return 0;
}
if (TREE_STATIC (field))
if (TREE_CODE (field) == VAR_DECL)
{
error ("field `%#D' is static; the only point of initialization is its definition",
field);
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;
}
......@@ -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
{
......
......@@ -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)
{
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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;
......
......@@ -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);
}
......@@ -4288,6 +4316,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)))
{
error ("attempt to take address of bit-field structure member `%D'",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment