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:
Mark Mitchell 2002-12-28 08:03:42 +00:00 committed by Mark Mitchell
parent 876200a8b7
commit a723baf1eb
24 changed files with 16158 additions and 1119 deletions

View File

@ -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

View File

@ -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

View File

@ -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)".

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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);
}

View File

@ -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
{

View File

@ -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;

View File

@ -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;

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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"

View File

@ -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;

View File

@ -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)))
{