[llvm-commits] CVS: gcc-3.4/gcc/cp/cp-lang.c cp-tree.h decl.c decl2.c method.c pt.c rtti.c semantics.c typeck.c
John Criswell
criswell at cs.uiuc.edu
Thu Feb 5 10:09:28 PST 2004
Changes in directory gcc-3.4/gcc/cp:
cp-lang.c updated: 1.2 -> 1.3
cp-tree.h updated: 1.2 -> 1.3
decl.c updated: 1.2 -> 1.3
decl2.c updated: 1.2 -> 1.3
method.c updated: 1.2 -> 1.3
pt.c updated: 1.2 -> 1.3
rtti.c updated: 1.2 -> 1.3
semantics.c updated: 1.2 -> 1.3
typeck.c updated: 1.2 -> 1.3
---
Log message:
Commit of merge from September 24, 2003 of mainline GCC. This merge now
works reasonably on Linux/x86 and probably works on Solaris/Sparc.
---
Diffs of the changes: (+772 -1011)
Index: gcc-3.4/gcc/cp/cp-lang.c
diff -u gcc-3.4/gcc/cp/cp-lang.c:1.2 gcc-3.4/gcc/cp/cp-lang.c:1.3
--- gcc-3.4/gcc/cp/cp-lang.c:1.2 Thu Jan 8 17:03:40 2004
+++ gcc-3.4/gcc/cp/cp-lang.c Thu Feb 5 10:05:46 2004
@@ -32,6 +32,11 @@
#include "diagnostic.h"
#include "cxx-pretty-print.h"
+#include "llvm-out.h"
+#ifdef EMIT_LLVM
+#include "llvm-internals.h"
+#endif
+
enum c_language_kind c_language = clk_cxx;
static HOST_WIDE_INT cxx_get_alias_set (tree);
@@ -42,6 +47,10 @@
static bool cp_var_mod_type_p (tree);
static void cxx_initialize_diagnostics (diagnostic_context *);
+#if EMIT_LLVM
+void llvm_cxx_expand_function_start ();
+#endif
+
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++"
#undef LANG_HOOKS_TREE_SIZE
@@ -110,6 +119,12 @@
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function
+#undef LANG_HOOKS_BUILTIN_TYPE_DECLS
+#define LANG_HOOKS_BUILTIN_TYPE_DECLS cxx_builtin_type_decls
+#undef LANG_HOOKS_PUSHLEVEL
+#define LANG_HOOKS_PUSHLEVEL lhd_do_nothing_i
+#undef LANG_HOOKS_POPLEVEL
+#define LANG_HOOKS_POPLEVEL lhd_do_nothing_iii_return_null_tree
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
@@ -123,6 +138,18 @@
#undef LANG_HOOKS_FUNCTION_FINAL
#define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context
+#undef LANG_HOOKS_RTL_EXPAND_START
+#define LANG_HOOKS_RTL_EXPAND_START cxx_expand_function_start
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+
+#ifdef EMIT_LLVM
+#undef LANG_HOOKS_LLVM_IR_EXPAND_START
+#define LANG_HOOKS_LLVM_IR_EXPAND_START llvm_cxx_expand_function_start
+#undef LANG_HOOKS_LLVM_IR_EXPAND_STMT
+#define LANG_HOOKS_LLVM_IR_EXPAND_STMT llvm_expand_stmt
+#endif
+
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
@@ -166,10 +193,12 @@
#undef LANG_HOOKS_EXPR_SIZE
#define LANG_HOOKS_EXPR_SIZE cp_expr_size
+#undef LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR cxx_callgraph_analyze_expr
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION expand_body
-#undef LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION
-#define LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION lower_function
+#undef LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_LLVM_CALLGRAPH_EXPAND_FUNCTION expand_body
#undef LANG_HOOKS_MAKE_TYPE
#define LANG_HOOKS_MAKE_TYPE cxx_make_type
@@ -187,6 +216,8 @@
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc-3.4/gcc/cp/cp-tree.h
diff -u gcc-3.4/gcc/cp/cp-tree.h:1.2 gcc-3.4/gcc/cp/cp-tree.h:1.3
--- gcc-3.4/gcc/cp/cp-tree.h:1.2 Thu Jan 8 17:03:40 2004
+++ gcc-3.4/gcc/cp/cp-tree.h Thu Feb 5 10:05:46 2004
@@ -39,6 +39,7 @@
IDENTIFIER_MARKED (IDENTIFIER_NODEs)
NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
+ COMPOUND_EXPR_OVERLOADED (in COMPOUND_EXPR).
TREE_INDIRECT_USING (in NAMESPACE_DECL).
ICS_USER_FLAG (in _CONV)
CLEANUP_P (in TRY_BLOCK)
@@ -46,6 +47,7 @@
PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
PARMLIST_ELLIPSIS_P (in PARMLIST)
DECL_PRETTY_FUNCTION_P (in VAR_DECL)
+ KOENIG_LOOKUP_P (in CALL_EXPR)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -796,7 +798,6 @@
int returns_abnormally;
int in_function_try_handler;
int in_base_initializer;
- int x_expanding_p;
/* True if this function can throw an exception. */
bool can_throw : 1;
@@ -858,17 +859,6 @@
#define current_function_returns_abnormally \
cp_function_chain->returns_abnormally
-/* Nonzero if we should generate RTL for functions that we process.
- When this is zero, we just accumulate tree structure, without
- interacting with the back end. */
-
-#define expanding_p cp_function_chain->x_expanding_p
-
-/* Nonzero if we are in the semantic analysis phase for the current
- function. */
-
-#define doing_semantic_analysis_p() (!expanding_p)
-
/* Nonzero if we are processing a base initializer. Zero elsewhere. */
#define in_base_initializer cp_function_chain->in_base_initializer
@@ -2293,6 +2283,14 @@
#define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
+/* Indicates that this is a non-dependent COMPOUND_EXPR which will
+ resolve to a function call. */
+#define COMPOUND_EXPR_OVERLOADED(NODE) TREE_LANG_FLAG_0 (NODE)
+
+/* In a CALL_EXPR appearing in a template, true if Koenig lookup
+ should be performed at instantiation time. */
+#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0(NODE)
+
/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
constructor call, rather than an ordinary function call. */
#define AGGR_INIT_VIA_CTOR_P(NODE) \
@@ -2932,15 +2930,27 @@
/* The kinds of scopes we recognize. */
typedef enum scope_kind {
- sk_block, /* An ordinary block scope. */
+ sk_block = 0, /* An ordinary block scope. This enumerator must
+ have the value zero because "cp_binding_level"
+ is initialized by using "memset" to set the
+ contents to zero, and the default scope kind
+ is "sk_block". */
+ sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
+ peusdo in that it is transparent to name lookup
+ activities. */
sk_try, /* A try-block. */
sk_catch, /* A catch-block. */
sk_for, /* The scope of the variable declared in a
for-init-statement. */
+ sk_function_parms, /* The scope containing function parameters. */
+ sk_class, /* The scope containing the members of a class. */
+ sk_namespace, /* The scope containing the members of a
+ namespace, including the global scope. */
sk_template_parms, /* A scope for template parameters. */
- sk_template_spec /* A scope corresponding to a template
- specialization. There is never anything in
- this scope. */
+ sk_template_spec /* Like sk_template_parms, but for an explicit
+ specialization. Since, by definition, an
+ explicit specialization is introduced by
+ "template <>", this scope is always empty. */
} scope_kind;
/* Various kinds of template specialization, instantiation, etc. */
@@ -3027,9 +3037,13 @@
(lookup_template_class use) */
tf_stmt_expr_cmpd = 1 << 6, /* tsubsting the compound statement of
a statement expr. */
- tf_stmt_expr_body = 1 << 7 /* tsubsting the statements in the
+ tf_stmt_expr_body = 1 << 7, /* tsubsting the statements in the
body of the compound statement of a
statement expr. */
+ tf_conv = 1 << 8 /* We are determining what kind of
+ conversion might be permissible,
+ not actually performing the
+ conversion. */
} tsubst_flags_t;
/* The kind of checking we can do looking in a class hierarchy. */
@@ -3084,7 +3098,7 @@
extern GTY(()) tree anonymous_namespace_name;
/* is_in_anonymous_namespace - Return true if the specified decl nodes is in an
- anonymous namespace! */
+ anonymous namespace! */
extern int is_in_anonymous_namespace(tree decl);
/* The number of function bodies which we are currently processing.
@@ -3528,7 +3542,7 @@
extern tree convert_for_arg_passing (tree, tree);
extern tree cp_convert_parm_for_inlining (tree, tree, tree);
extern bool is_properly_derived_from (tree, tree);
-extern tree initialize_reference (tree, tree, tree);
+extern tree initialize_reference (tree, tree, tree, tree *);
extern tree make_temporary_var_for_ref_to_temp (tree, tree);
extern tree strip_top_quals (tree);
extern tree perform_implicit_conversion (tree, tree);
@@ -3602,7 +3616,6 @@
extern int global_bindings_p (void);
extern int kept_level_p (void);
extern tree getdecls (void);
-extern void pushlevel (int);
extern void insert_block (tree);
extern void set_block (tree);
extern tree pushdecl (tree);
@@ -3615,11 +3628,12 @@
extern void cxx_mark_function_context (struct function *);
extern int toplevel_bindings_p (void);
extern int namespace_bindings_p (void);
-extern void keep_next_level (int);
+extern void keep_next_level (bool);
+extern scope_kind innermost_scope_kind (void);
extern int template_parm_scope_p (void);
extern void set_class_shadows (tree);
extern void maybe_push_cleanup_level (tree);
-extern void begin_scope (scope_kind);
+extern cxx_scope *begin_scope (scope_kind, tree);
extern void finish_scope (void);
extern void resume_level (struct cp_binding_level *);
extern void delete_block (tree);
@@ -3748,7 +3762,8 @@
extern tmpl_spec_kind current_tmpl_spec_kind (int);
extern tree cp_fname_init (const char *);
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
-extern int add_binding (cxx_binding *, tree);
+extern tree cxx_builtin_type_decls (void);
+
extern bool have_extern_spec;
/* in decl2.c */
@@ -3801,7 +3816,7 @@
extern tree get_guard (tree);
extern tree get_guard_cond (tree);
extern tree set_guard (tree);
-extern void lower_function (tree);
+extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
/* XXX Not i18n clean. */
#define cp_deprecated(STR) \
@@ -4114,7 +4129,7 @@
extern tree finish_stmt_expr_expr (tree);
extern tree finish_stmt_expr (tree, bool);
extern tree perform_koenig_lookup (tree, tree);
-extern tree finish_call_expr (tree, tree, bool);
+extern tree finish_call_expr (tree, tree, bool, bool);
extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void);
extern tree finish_object_call_expr (tree, tree, tree);
@@ -4141,11 +4156,10 @@
bool, bool, bool *,
const char **);
extern tree finish_typeof (tree);
-extern tree finish_sizeof (tree);
-extern tree finish_alignof (tree);
extern void finish_decl_cleanup (tree, tree);
extern void finish_eh_cleanup (tree);
extern void expand_body (tree);
+extern void cxx_expand_function_start (void);
extern tree nullify_returns_r (tree *, int *, void *);
extern void do_pushlevel (scope_kind);
extern tree do_poplevel (void);
@@ -4170,13 +4184,10 @@
extern tree canonical_type_variant (tree);
extern tree copy_base_binfos (tree, tree, tree);
extern int member_p (tree);
-extern cp_lvalue_kind real_lvalue_p (tree);
-extern int non_cast_lvalue_p (tree);
-extern cp_lvalue_kind real_non_cast_lvalue_p (tree);
-extern int non_cast_lvalue_or_else (tree, const char *);
-extern tree build_min (enum tree_code, tree,
- ...);
+extern cp_lvalue_kind real_lvalue_p (tree);
+extern tree build_min (enum tree_code, tree, ...);
extern tree build_min_nt (enum tree_code, ...);
+extern tree build_min_non_dep (enum tree_code, tree, ...);
extern tree build_cplus_new (tree, tree);
extern tree get_target_expr (tree);
extern tree build_cplus_staticfn_type (tree, tree, tree);
@@ -4254,8 +4265,8 @@
extern bool compparms (tree, tree);
extern int comp_cv_qualification (tree, tree);
extern int comp_cv_qual_signature (tree, tree);
-extern tree expr_sizeof (tree);
-extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, int);
+extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code);
+extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
#define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
extern tree inline_conversion (tree);
extern tree decay_conversion (tree);
Index: gcc-3.4/gcc/cp/decl.c
diff -u gcc-3.4/gcc/cp/decl.c:1.2 gcc-3.4/gcc/cp/decl.c:1.3
--- gcc-3.4/gcc/cp/decl.c:1.2 Thu Jan 8 17:03:40 2004
+++ gcc-3.4/gcc/cp/decl.c Thu Feb 5 10:05:46 2004
@@ -56,7 +56,6 @@
static tree grokparms (tree);
static const char *redeclaration_error_message (tree, tree);
-static void push_binding_level (cxx_scope *);
static void pop_binding_level (void);
static void suspend_binding_level (void);
static void resume_binding_level (struct cp_binding_level *);
@@ -69,7 +68,7 @@
static tree lookup_tag_reverse (tree, tree);
static void push_local_name (tree);
static void warn_extern_redeclared_static (tree, tree);
-static tree grok_reference_init (tree, tree, tree);
+static tree grok_reference_init (tree, tree, tree, tree *);
static tree grokfndecl (tree, tree, tree, tree, int,
enum overload_flags, tree,
tree, int, int, int, int, int, int, tree);
@@ -118,7 +117,7 @@
static void maybe_deduce_size_from_array_init (tree, tree);
static void layout_var_decl (tree);
static void maybe_commonize_var (tree);
-static tree check_initializer (tree, tree, int);
+static tree check_initializer (tree, tree, int, tree *);
static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
static void save_function_data (tree);
static void check_function_type (tree, tree);
@@ -371,51 +370,27 @@
TREE_LIST; the TREE_VALUE is the actual declaration. */
tree dead_vars_from_for;
- /* 1 for the level that holds the parameters of a function.
- 2 for the level that holds a class declaration. */
- unsigned parm_flag : 2;
-
- /* 1 means make a BLOCK for this level regardless of all else.
- 2 for temporary binding contours created by the compiler. */
- unsigned keep : 2;
+ /* Binding depth at which this level began. */
+ int binding_depth;
+
+ /* The kind of scope that this object represents. However, a
+ SK_TEMPLATE_SPEC scope is represented with KIND set to
+ SK_TEMPALTE_PARMS and EXPLICIT_SPEC_P set to true. */
+ enum scope_kind kind : 4;
+
+ /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
+ only valid if KIND == SK_TEMPLATE_PARMS. */
+ bool explicit_spec_p : 1;
- /* Nonzero if this level "doesn't exist" for tags. */
- unsigned tag_transparent : 1;
+ /* true means make a BLOCK for this level regardless of all else. */
+ unsigned keep : 1;
/* Nonzero if this level can safely have additional
cleanup-needing variables added to it. */
unsigned more_cleanups_ok : 1;
unsigned have_cleanups : 1;
- /* Nonzero if this scope is for storing the decls for template
- parameters and generic decls; these decls will be discarded and
- replaced with a TEMPLATE_DECL. */
- unsigned template_parms_p : 1;
-
- /* Nonzero if this scope corresponds to the `<>' in a
- `template <>' clause. Whenever this flag is set,
- TEMPLATE_PARMS_P will be set as well. */
- unsigned template_spec_p : 1;
-
- /* This is set for a namespace binding level. */
- unsigned namespace_p : 1;
-
- /* True if this level is that of a for-statement where we need to
- worry about ambiguous (ARM or ISO) scope rules. */
- unsigned is_for_scope : 1;
-
- /* True if this level corresponds to a TRY block. Currently this
- information is only available while building the tree structure. */
- unsigned is_try_scope : 1;
-
- /* True if this level corresponds to a CATCH block. Currently this
- information is only available while building the tree structure. */
- unsigned is_catch_scope : 1;
-
- /* Three bits left for this word. */
-
- /* Binding depth at which this level began. */
- unsigned binding_depth;
+ /* 22 bits left to fill a 32-bit word. */
};
#define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL)
@@ -435,9 +410,9 @@
static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
-/* Nonzero means unconditionally make a BLOCK for the next level pushed. */
+/* true means unconditionally make a BLOCK for the next level pushed. */
-static int keep_next_level_flag;
+static bool keep_next_level_flag;
/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or
UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the
@@ -469,28 +444,24 @@
static const char *
cxx_scope_descriptor (cxx_scope *scope)
{
- const char *desc;
-
- if (scope->namespace_p)
- desc = "namespace-scope";
- else if (scope->parm_flag == 1)
- desc = "function-prototype-scope";
- else if (scope->parm_flag == 2)
- desc = "class-scope";
- else if (scope->is_for_scope)
- desc = "for-scope";
- else if (scope->is_try_scope)
- desc = "try-scope";
- else if (scope->is_catch_scope)
- desc = "catch-scope";
- else if (scope->template_spec_p)
- desc = "template-explicit-spec-scope";
- else if (scope->template_parms_p)
- desc = "template-prototype-scope";
- else
- desc = "block-scope";
+ /* The order of this table must match the "scope_kind"
+ enumerators. */
+ static const char* scope_kind_names[] = {
+ "block-scope",
+ "cleanup-scope",
+ "try-scope",
+ "catch-scope",
+ "for-scope",
+ "function-parameter-scope",
+ "class-scope",
+ "namespace-scope",
+ "template-parameter-scope",
+ "template-explicit-spec-scope"
+ };
+ const scope_kind kind = scope->explicit_spec_p
+ ? sk_template_spec : scope->kind;
- return desc;
+ return scope_kind_names[kind];
}
/* Output a debugging information about SCOPE when performning
@@ -506,10 +477,27 @@
verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
}
-/* Construct a scope that may be TAG-TRANSPARENT, the sub-blocks of
- which may be KEPT. */
-static inline cxx_scope *
-make_cxx_scope (bool tag_transparent, int keep)
+/* Return the estimated initial size of the hashtable of a NAMESPACE
+ scope. */
+
+static inline size_t
+namespace_scope_ht_size (tree ns)
+{
+ tree name = DECL_NAME (ns);
+
+ return name == std_identifier
+ ? NAMESPACE_STD_HT_SIZE
+ : (name == global_scope_name
+ ? GLOBAL_SCOPE_HT_SIZE
+ : NAMESPACE_ORDINARY_HT_SIZE);
+}
+
+/* Create a new KIND scope and make it the top of the active scopes stack.
+ ENTITY is the scope of the associated C++ entity (namespace, class,
+ function); it is NULL otherwise. */
+
+cxx_scope *
+begin_scope (scope_kind kind, tree entity)
{
cxx_scope *scope;
@@ -521,31 +509,62 @@
}
else
scope = ggc_alloc (sizeof (cxx_scope));
-
memset (scope, 0, sizeof (cxx_scope));
- scope->tag_transparent = tag_transparent;
- scope->keep = keep;
+
+ scope->this_entity = entity;
scope->more_cleanups_ok = true;
+ switch (kind)
+ {
+ case sk_cleanup:
+ scope->keep = true;
+ break;
+
+ case sk_template_spec:
+ scope->explicit_spec_p = true;
+ kind = sk_template_parms;
+ /* fall through */
+ case sk_template_parms:
+ case sk_block:
+ case sk_try:
+ case sk_catch:
+ case sk_for:
+ case sk_class:
+ case sk_function_parms:
+ scope->keep = keep_next_level_flag;
+ break;
- return scope;
-}
+ case sk_namespace:
+ scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));
+ NAMESPACE_LEVEL (entity) = scope;
+ VARRAY_TREE_INIT (scope->static_decls,
+ DECL_NAME (entity) == std_identifier
+ || DECL_NAME (entity) == global_scope_name
+ ? 200 : 10,
+ "Static declarations");
+ break;
-static void
-push_binding_level (cxx_scope *newlevel)
-{
- /* Add this level to the front of the chain (stack) of levels that
- are active. */
- newlevel->level_chain = current_binding_level;
- current_binding_level = newlevel;
+ default:
+ /* Should not happen. */
+ my_friendly_assert (false, 20030922);
+ break;
+ }
+ scope->kind = kind;
+
+ /* Add it to the front of currently active scopes stack. */
+ scope->level_chain = current_binding_level;
+ current_binding_level = scope;
+ keep_next_level_flag = false;
if (ENABLE_SCOPE_CHECKING)
{
- newlevel->binding_depth = binding_depth;
+ scope->binding_depth = binding_depth;
indent (binding_depth);
- cxx_scope_debug (newlevel, input_location.line, "push");
+ cxx_scope_debug (scope, input_location.line, "push");
is_class_level = 0;
binding_depth++;
}
+
+ return scope;
}
/* Find the innermost enclosing class scope, and reset
@@ -556,9 +575,9 @@
{
struct cp_binding_level *level = current_binding_level;
- while (level && level->parm_flag != 2)
+ while (level && level->kind != sk_class)
level = level->level_chain;
- if (level && level->parm_flag == 2)
+ if (level && level->kind == sk_class)
class_binding_level = level;
else
class_binding_level = 0;
@@ -587,7 +606,7 @@
register struct cp_binding_level *level = current_binding_level;
current_binding_level = current_binding_level->level_chain;
level->level_chain = free_binding_level;
- if (level->parm_flag == 2)
+ if (level->kind == sk_class)
level->type_decls = NULL;
else
binding_table_free (level->type_decls);
@@ -660,7 +679,7 @@
struct cp_binding_level *b;
b = current_binding_level;
- while (b->parm_flag == 2)
+ while (b->kind == sk_class)
b = b->level_chain;
return b;
@@ -677,7 +696,7 @@
{
struct cp_binding_level *b = innermost_nonclass_level ();
- return b->namespace_p || b->template_parms_p;
+ return b->kind == sk_namespace || b->kind == sk_template_parms;
}
/* Nonzero if this is a namespace scope, or if we are defining a class
@@ -689,15 +708,15 @@
{
struct cp_binding_level *b = innermost_nonclass_level ();
- return b->namespace_p;
+ return b->kind == sk_namespace;
}
-/* If KEEP is nonzero, make a BLOCK node for the next binding level,
+/* If KEEP is true, make a BLOCK node for the next binding level,
unconditionally. Otherwise, use the normal logic to decide whether
or not to create a BLOCK. */
void
-keep_next_level (int keep)
+keep_next_level (bool keep)
{
keep_next_level_flag = keep;
}
@@ -709,9 +728,17 @@
{
return (current_binding_level->blocks != NULL_TREE
|| current_binding_level->keep
+ || current_binding_level->kind == sk_cleanup
|| current_binding_level->names != NULL_TREE
- || (current_binding_level->type_decls != NULL
- && !current_binding_level->tag_transparent));
+ || current_binding_level->type_decls != NULL);
+}
+
+/* Returns the kind of the innermost scope. */
+
+scope_kind
+innermost_scope_kind (void)
+{
+ return current_binding_level->kind;
}
/* Returns nonzero if this scope was created to store template
@@ -720,7 +747,7 @@
int
template_parm_scope_p (void)
{
- return current_binding_level->template_parms_p;
+ return innermost_scope_kind () == sk_template_parms;
}
/* Returns the kind of template specialization we are currently
@@ -736,7 +763,9 @@
struct cp_binding_level *b;
/* Scan through the template parameter scopes. */
- for (b = current_binding_level; b->template_parms_p; b = b->level_chain)
+ for (b = current_binding_level;
+ b->kind == sk_template_parms;
+ b = b->level_chain)
{
/* If we see a specialization scope inside a parameter scope,
then something is wrong. That corresponds to a declaration
@@ -747,7 +776,7 @@
which is always invalid since [temp.expl.spec] forbids the
specialization of a class member template if the enclosing
class templates are not explicitly specialized as well. */
- if (b->template_spec_p)
+ if (b->explicit_spec_p)
{
if (n_template_parm_scopes == 0)
innermost_specialization_p = 1;
@@ -817,20 +846,6 @@
class_binding_level->class_shadowed = shadows;
}
-/* Enter a new binding level.
- If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
- not for that of tags. */
-
-void
-pushlevel (int tag_transparent)
-{
- if (cfun && !doing_semantic_analysis_p ())
- return;
-
- push_binding_level (make_cxx_scope (tag_transparent, keep_next_level_flag));
- keep_next_level_flag = 0;
-}
-
/* We're defining an object of type TYPE. If it needs a cleanup, but
we're not allowed to add any more objects with cleanups to the current
scope, create a new binding level. */
@@ -841,50 +856,11 @@
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& current_binding_level->more_cleanups_ok == 0)
{
- keep_next_level (2);
- pushlevel (1);
+ begin_scope (sk_cleanup, NULL);
clear_last_expr ();
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
}
}
-
-/* Enter a new scope. The KIND indicates what kind of scope is being
- created. */
-
-void
-begin_scope (scope_kind sk)
-{
- pushlevel (0);
-
- switch (sk)
- {
- case sk_block:
- break;
-
- case sk_try:
- current_binding_level->is_try_scope = 1;
- break;
-
- case sk_catch:
- current_binding_level->is_catch_scope = 1;
- break;
-
- case sk_for:
- current_binding_level->is_for_scope = 1;
- break;
-
- case sk_template_spec:
- current_binding_level->template_spec_p = 1;
- /* Fall through. */
-
- case sk_template_parms:
- current_binding_level->template_parms_p = 1;
- break;
-
- default:
- abort ();
- }
-}
/* Exit the current scope. */
@@ -912,82 +888,6 @@
IDENTIFIER_BINDING (id) = binding;
}
-/* ID is already bound in the current scope. But, DECL is an
- additional binding for ID in the same scope. This is the `struct
- stat' hack whereby a non-typedef class-name or enum-name can be
- bound at the same level as some other kind of entity. It's the
- responsibility of the caller to check that inserting this name is
- valid here. Returns nonzero if the new binding was successful. */
-
-int
-add_binding (cxx_binding *binding, tree decl)
-{
- tree bval = BINDING_VALUE (binding);
- int ok = 1;
-
- timevar_push (TV_NAME_LOOKUP);
- if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
- /* The new name is the type name. */
- BINDING_TYPE (binding) = decl;
- else if (!bval)
- /* This situation arises when push_class_level_binding moves an
- inherited type-binding out of the way to make room for a new
- value binding. */
- BINDING_VALUE (binding) = decl;
- else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
- {
- /* The old binding was a type name. It was placed in
- BINDING_VALUE because it was thought, at the point it was
- declared, to be the only entity with such a name. Move the
- type name into the type slot; it is now hidden by the new
- binding. */
- BINDING_TYPE (binding) = bval;
- BINDING_VALUE (binding) = decl;
- INHERITED_VALUE_BINDING_P (binding) = 0;
- }
- else if (TREE_CODE (bval) == TYPE_DECL
- && TREE_CODE (decl) == TYPE_DECL
- && DECL_NAME (decl) == DECL_NAME (bval)
- && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
- /* If either type involves template parameters, we must
- wait until instantiation. */
- || uses_template_parms (TREE_TYPE (decl))
- || uses_template_parms (TREE_TYPE (bval))))
- /* We have two typedef-names, both naming the same type to have
- the same name. This is OK because of:
-
- [dcl.typedef]
-
- In a given scope, a typedef specifier can be used to redefine
- the name of any type declared in that scope to refer to the
- type to which it already refers. */
- ok = 0;
- /* There can be two block-scope declarations of the same variable,
- so long as they are `extern' declarations. However, there cannot
- be two declarations of the same static data member:
-
- [class.mem]
-
- A member shall not be declared twice in the
- member-specification. */
- else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
- && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
- && !DECL_CLASS_SCOPE_P (decl))
- {
- duplicate_decls (decl, BINDING_VALUE (binding));
- ok = 0;
- }
- else
- {
- error ("declaration of `%#D'", decl);
- cp_error_at ("conflicts with previous declaration `%#D'",
- BINDING_VALUE (binding));
- ok = 0;
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
-}
-
/* Add DECL to the list of things declared in B. */
static void
@@ -1014,7 +914,7 @@
b->names_size++;
/* If appropriate, add decl to separate list of statics */
- if (b->namespace_p)
+ if (b->kind == sk_namespace)
if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
|| (TREE_CODE (decl) == FUNCTION_DECL
&& (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
@@ -1034,14 +934,12 @@
/* Skip over any local classes. This makes sense if we call
push_local_binding with a friend decl of a local class. */
- b = current_binding_level;
- while (b->parm_flag == 2)
- b = b->level_chain;
+ b = innermost_nonclass_level ();
if (lookup_name_current_level (id))
{
/* Supplement the existing binding. */
- if (!add_binding (IDENTIFIER_BINDING (id), decl))
+ if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
/* It didn't work. Something else must be bound at this
level. Do not add DECL to the list of things to pop
later. */
@@ -1080,7 +978,7 @@
if (binding && BINDING_SCOPE (binding) == class_binding_level)
/* Supplement the existing binding. */
- result = add_binding (IDENTIFIER_BINDING (id), decl);
+ result = supplement_binding (IDENTIFIER_BINDING (id), decl);
else
/* Create a new binding. */
push_binding (id, decl, class_binding_level);
@@ -1168,7 +1066,7 @@
static void
pop_label (tree label, tree old_value)
{
- if (!processing_template_decl && doing_semantic_analysis_p ())
+ if (!processing_template_decl)
{
if (DECL_INITIAL (label) == NULL_TREE)
{
@@ -1238,15 +1136,13 @@
tree block = NULL_TREE;
tree decl;
int leaving_for_scope;
+ scope_kind kind;
timevar_push (TV_NAME_LOOKUP);
- if (cfun && !doing_semantic_analysis_p ())
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- my_friendly_assert (current_binding_level->parm_flag != 2,
- 19990916);
+ my_friendly_assert (current_binding_level->kind != sk_class, 19990916);
- real_functionbody = (current_binding_level->keep == 2
+ real_functionbody = (current_binding_level->kind == sk_cleanup
? ((functionbody = 0), tmp) : functionbody);
subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
@@ -1258,7 +1154,7 @@
rather than the end. This hack is no longer used. */
my_friendly_assert (keep == 0 || keep == 1, 0);
- if (current_binding_level->keep == 1)
+ if (current_binding_level->keep)
keep = 1;
/* Any uses of undefined labels, and any defined labels, now operate
@@ -1275,9 +1171,9 @@
if (labels->binding_level == current_binding_level)
{
tree decl;
- if (current_binding_level->is_try_scope)
+ if (current_binding_level->kind == sk_try)
labels->in_try_scope = 1;
- if (current_binding_level->is_catch_scope)
+ if (current_binding_level->kind == sk_catch)
labels->in_catch_scope = 1;
for (decl = labels->names_in_scope; decl;
decl = TREE_CHAIN (decl))
@@ -1359,7 +1255,7 @@
ended. We only use the new rules if flag_new_for_scope is
nonzero. */
leaving_for_scope
- = current_binding_level->is_for_scope && flag_new_for_scope == 1;
+ = current_binding_level->kind == sk_for && flag_new_for_scope == 1;
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
@@ -1490,7 +1386,7 @@
pop_labels (block);
}
- tmp = current_binding_level->keep;
+ kind = current_binding_level->kind;
pop_binding_level ();
if (functionbody)
@@ -1515,7 +1411,7 @@
TREE_USED (block) = 1;
/* Take care of compiler's internal binding structures. */
- if (tmp == 2)
+ if (kind == sk_cleanup)
{
tree scope_stmts;
@@ -1576,7 +1472,6 @@
{
/* The RTL expansion machinery requires us to provide this callback,
but it is not applicable in function-at-a-time mode. */
- my_friendly_assert (cfun && !doing_semantic_analysis_p (), 20000911);
}
/* Do a pushlevel for class declarations. */
@@ -1587,11 +1482,7 @@
if (ENABLE_SCOPE_CHECKING)
is_class_level = 1;
- push_binding_level (make_cxx_scope (false, 0));
-
- class_binding_level = current_binding_level;
- class_binding_level->parm_flag = 2;
- class_binding_level->this_entity = current_class_type;
+ class_binding_level = begin_scope (sk_class, current_class_type);
}
/* ...and a poplevel for class declarations. */
@@ -1623,7 +1514,7 @@
/* Find the next enclosing class, and recreate
IDENTIFIER_CLASS_VALUEs appropriate for that class. */
b = level->level_chain;
- while (b && b->parm_flag != 2)
+ while (b && b->kind != sk_class)
b = b->level_chain;
if (b)
@@ -1898,8 +1789,6 @@
tree t;
int i = 0, len;
fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
- if (lvl->tag_transparent)
- fprintf (stderr, " tag-transparent");
if (lvl->more_cleanups_ok)
fprintf (stderr, " more-cleanups-ok");
if (lvl->have_cleanups)
@@ -2005,32 +1894,17 @@
the identifier is polymorphic, with three possible values:
NULL_TREE, a list of "cxx_binding"s. */
-
-/* Push the initial binding contour of NAMESPACE-scope. Any subsequent
- push of NS is actually a resume. */
-static void
-initial_push_namespace_scope (tree ns)
-{
- tree name = DECL_NAME (ns);
- cxx_scope *scope;
-
- pushlevel (0);
- scope = current_binding_level;
- scope->namespace_p = true;
- scope->type_decls = binding_table_new (name == std_identifier
- ? NAMESPACE_STD_HT_SIZE
- : (name == global_scope_name
- ? GLOBAL_SCOPE_HT_SIZE
- : NAMESPACE_ORDINARY_HT_SIZE));
- VARRAY_TREE_INIT (scope->static_decls,
- name == std_identifier || name == global_scope_name
- ? 200 : 10,
- "Static declarations");
- scope->this_entity = ns;
- NAMESPACE_LEVEL (ns) = scope;
-}
-
-
+/*
+ * Function: is_in_anonymous_namespace ()
+ *
+ * Description:
+ * This function takes a GCC internal tree and determines whether it was
+ * declared an anonymous namespace.
+ *
+ * Return value:
+ * 0 - This tree was not declared in an anonymous namespace.
+ * 1 - This tree was declared in an anonymous namespace.
+ */
int is_in_anonymous_namespace(tree decl) {
tree Context;
if (decl && DECL_P(decl))
@@ -2062,9 +1936,8 @@
}
-
-/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then
- we use the anonymous namespace. */
+/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
+ select a name that is unique to this compilation unit. */
void
push_namespace (tree name)
@@ -2121,7 +1994,7 @@
d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
d = pushdecl (d);
- initial_push_namespace_scope (d);
+ begin_scope (sk_namespace, d);
}
else
resume_binding_level (NAMESPACE_LEVEL (d));
@@ -2282,13 +2155,13 @@
inserted into namespace level, finish_file wouldn't find them
when doing pending instantiations. Therefore, don't stop at
namespace level, but continue until :: . */
- if (global_scope_p (b) || (pseudo && b->template_parms_p))
+ if (global_scope_p (b) || (pseudo && b->kind == sk_template_parms))
break;
old_bindings = store_bindings (b->names, old_bindings);
/* We also need to check class_shadowed to save class-level type
bindings, since pushclass doesn't fill in b->names. */
- if (b->parm_flag == 2)
+ if (b->kind == sk_class)
old_bindings = store_bindings (b->class_shadowed, old_bindings);
/* Unwind type-value slots back to top level. */
@@ -2359,7 +2232,7 @@
{
tree type;
- if (!b->namespace_p)
+ if (b->kind != sk_namespace)
{
/* Shadow the marker, not the real thing, so that the marker
gets restored later. */
@@ -2375,7 +2248,7 @@
if (decl)
{
if (BINDING_VALUE (binding))
- add_binding (binding, decl);
+ supplement_binding (binding, decl);
else
BINDING_VALUE (binding) = decl;
}
@@ -2426,7 +2299,7 @@
verbatim ("XXX entering pop_everything ()\n");
while (!toplevel_bindings_p ())
{
- if (current_binding_level->parm_flag == 2)
+ if (current_binding_level->kind == sk_class)
pop_nested_class ();
else
poplevel (0, 0, 0);
@@ -2482,8 +2355,8 @@
friend case, push_template_decl will already have put the
friend into global scope, if appropriate. */
if (TREE_CODE (type) != ENUMERAL_TYPE
- && !globalize && b->template_parms_p
- && b->level_chain->parm_flag == 2)
+ && !globalize && b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class)
{
finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
/* Put this UDT in the table of UDTs for the class, since
@@ -2567,7 +2440,7 @@
}
/* Push a tag name NAME for struct/class/union/enum type TYPE.
- Normally put it into the inner-most non-tag-transparent scope,
+ Normally put it into the inner-most non-sk_cleanup scope,
but if GLOBALIZE is true, put it in the inner-most non-class scope.
The latter is needed for implicit declarations. */
@@ -2578,8 +2451,8 @@
timevar_push (TV_NAME_LOOKUP);
b = current_binding_level;
- while (b->tag_transparent
- || (b->parm_flag == 2
+ while (b->kind == sk_cleanup
+ || (b->kind == sk_class
&& (globalize
/* We may be defining a new type in the initializer
of a static member variable. We allow this when
@@ -2616,8 +2489,9 @@
if (!context)
context = current_namespace;
- if ((b->template_parms_p && b->level_chain->parm_flag == 2)
- || b->parm_flag == 2)
+ if (b->kind == sk_class
+ || (b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class))
in_class = 1;
if (current_lang_name == lang_name_java)
@@ -2631,7 +2505,7 @@
d = maybe_process_template_type_declaration (type,
globalize, b);
- if (b->parm_flag == 2)
+ if (b->kind == sk_class)
{
if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
/* Put this TYPE_DECL on the TYPE_FIELDS list for the
@@ -2661,14 +2535,12 @@
&& !processing_template_decl)
VARRAY_PUSH_TREE (local_classes, type);
}
- if (b->parm_flag == 2)
+ if (b->kind == sk_class
+ && !COMPLETE_TYPE_P (current_class_type))
{
- if (!COMPLETE_TYPE_P (current_class_type))
- {
- maybe_add_class_template_decl_list (current_class_type,
- type, /*friend_p=*/0);
- CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
- }
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+ CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
}
}
@@ -2721,7 +2593,7 @@
return;
b = current_binding_level;
- while (b->tag_transparent)
+ while (b->kind == sk_cleanup)
b = b->level_chain;
if (b->type_decls != NULL)
binding_table_remove_anonymous_types (b->type_decls);
@@ -2851,7 +2723,8 @@
if (TREE_CODE (newdecl) == TYPE_DECL
|| TREE_CODE (newdecl) == TEMPLATE_DECL
- || TREE_CODE (newdecl) == CONST_DECL)
+ || TREE_CODE (newdecl) == CONST_DECL
+ || TREE_CODE (newdecl) == NAMESPACE_DECL)
return;
/* Don't get confused by static member functions; that's a different
@@ -2922,19 +2795,18 @@
&& DECL_UNINLINABLE (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
{
- warning ("%Hfunction '%D' redeclared as inline",
- &DECL_SOURCE_LOCATION (newdecl), newdecl);
- warning ("%Hprevious declaration of '%D' with attribute noinline",
- &DECL_SOURCE_LOCATION (olddecl), olddecl);
+ warning ("%Jfunction '%D' redeclared as inline", newdecl, newdecl);
+ warning ("%Jprevious declaration of '%D' with attribute noinline",
+ olddecl, olddecl);
}
else if (DECL_DECLARED_INLINE_P (olddecl)
&& DECL_UNINLINABLE (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
{
- warning ("%Hfunction '%D' redeclared with attribute noinline",
- &DECL_SOURCE_LOCATION (newdecl), newdecl);
- warning ("%Hprevious declaration of '%D' was inline",
- &DECL_SOURCE_LOCATION (olddecl), olddecl);
+ warning ("%Jfunction '%D' redeclared with attribute noinline",
+ newdecl, newdecl);
+ warning ("%Jprevious declaration of '%D' was inline",
+ olddecl, olddecl);
}
}
@@ -2979,9 +2851,9 @@
if (DECL_ANTICIPATED (olddecl))
; /* Do nothing yet. */
else if ((DECL_EXTERN_C_P (newdecl)
- && DECL_EXTERN_C_P (olddecl))
- || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
- TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
+ && DECL_EXTERN_C_P (olddecl))
+ || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
+ TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
{
/* A near match; override the builtin. */
@@ -3010,6 +2882,10 @@
else if (DECL_ANTICIPATED (olddecl))
TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+ /* Whether or not the builtin can throw exceptions has no
+ bearing on this declarator. */
+ TREE_NOTHROW (olddecl) = 0;
+
if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
{
/* If a builtin function is redeclared as `static', merge
@@ -3119,8 +2995,10 @@
else if (current_class_type == NULL_TREE
|| IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
{
- error ("conflicting types for `%#D'", newdecl);
- cp_error_at ("previous declaration as `%#D'", olddecl);
+ error ("conflicting declaration '%#D'", newdecl);
+ cp_error_at ("'%D' has a previous declaration as `%#D'",
+ olddecl, olddecl);
+ return false;
}
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL
@@ -3174,8 +3052,7 @@
{
/* Prototype decl follows defn w/o prototype. */
cp_warning_at ("prototype for `%#D'", newdecl);
- warning ("%Hfollows non-prototype definition here",
- &DECL_SOURCE_LOCATION (olddecl));
+ warning ("%Jfollows non-prototype definition here", olddecl);
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
@@ -3230,10 +3107,8 @@
&& ! DECL_DECLARED_INLINE_P (olddecl)
&& TREE_ADDRESSABLE (olddecl) && warn_inline)
{
- warning ("`%#D' was used before it was declared inline",
- newdecl);
- warning ("%Hprevious non-inline declaration here",
- &DECL_SOURCE_LOCATION (olddecl));
+ warning ("`%#D' was used before it was declared inline", newdecl);
+ warning ("%Jprevious non-inline declaration here", olddecl);
}
}
}
@@ -3679,10 +3554,6 @@
int need_new_binding;
timevar_push (TV_NAME_LOOKUP);
- /* We shouldn't be calling pushdecl when we're generating RTL for a
- function that we already did semantic analysis on previously. */
- my_friendly_assert (!cfun || doing_semantic_analysis_p (),
- 19990913);
need_new_binding = 1;
@@ -4063,10 +3934,10 @@
b = b->level_chain;
/* ARM $8.3 */
- if (b->parm_flag == 1)
+ if (b->kind == sk_function_parms)
{
error ("declaration of `%#D' shadows a parameter",
- name);
+ name);
err = true;
}
}
@@ -4127,7 +3998,7 @@
timevar_push (TV_NAME_LOOKUP);
current_function_decl = NULL_TREE;
- if (level->parm_flag == 2)
+ if (level->kind == sk_class)
{
b = class_binding_level;
class_binding_level = level;
@@ -4694,9 +4565,6 @@
tree decl;
decl = build_decl (LABEL_DECL, id, void_type_node);
- if (expanding_p)
- /* Make sure every label has an rtx. */
- label_rtx (decl);
DECL_CONTEXT (decl) = current_function_decl;
DECL_MODE (decl) = VOIDmode;
@@ -4865,7 +4733,7 @@
if (b == level)
break;
- if ((b->is_try_scope || b->is_catch_scope) && ! saw_eh)
+ if ((b->kind == sk_try || b->kind == sk_catch) && ! saw_eh)
{
if (! identified)
{
@@ -4878,7 +4746,7 @@
pedwarn ("%H from here", locus);
identified = 1;
}
- if (b->is_try_scope)
+ if (b->kind == sk_try)
error (" enters try block");
else
error (" enters catch block");
@@ -4970,7 +4838,7 @@
if (u > 1 && DECL_ARTIFICIAL (b))
/* Can't skip init of __exception_info. */
- error ("%H enters catch block", &DECL_SOURCE_LOCATION (b));
+ error ("%J enters catch block", b);
else if (u > 1)
cp_error_at (" skips initialization of `%#D'", b);
else
@@ -4984,8 +4852,7 @@
}
/* Define a label, specifying the location in the source file.
- Return the LABEL_DECL node for the label, if the definition is valid.
- Otherwise return 0. */
+ Return the LABEL_DECL node for the label. */
tree
define_label (location_t location, tree name)
@@ -5001,17 +4868,16 @@
/* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
p->more_cleanups_ok = 0;
if (name == get_identifier ("wchar_t"))
pedwarn ("label named wchar_t");
if (DECL_INITIAL (decl) != NULL_TREE)
- {
- error ("duplicate label `%D'", decl);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
+ error ("duplicate label `%D'", decl);
else
{
/* Mark label as having been defined. */
@@ -5024,9 +4890,10 @@
ent->binding_level = current_binding_level;
}
check_previous_gotos (decl);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
}
+
timevar_pop (TV_NAME_LOOKUP);
+ return decl;
}
struct cp_switch
@@ -5118,7 +4985,9 @@
/* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
p->more_cleanups_ok = 0;
return r;
@@ -5198,7 +5067,7 @@
return the structure (or union or enum) definition for that name.
Searches binding levels from BINDING_SCOPE up to the global level.
If THISLEVEL_ONLY is nonzero, searches only the specified context
- (but skips any tag-transparent contexts to find one that is
+ (but skips any sk_cleanup contexts to find one that is
meaningful for tags).
FORM says which kind of type the caller wants;
it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
@@ -5227,7 +5096,7 @@
if (type != NULL)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
}
- else if (level->namespace_p)
+ else if (level->kind == sk_namespace)
/* Do namespace lookup. */
for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
{
@@ -5286,9 +5155,9 @@
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
}
}
- if (thislevel_only && ! level->tag_transparent)
+ if (thislevel_only && level->kind != sk_cleanup)
{
- if (level->template_parms_p && allow_template_parms_p)
+ if (level->kind == sk_template_parms && allow_template_parms_p)
{
/* We must deal with cases like this:
@@ -5751,7 +5620,7 @@
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
- !level->namespace_p;
+ level->kind != sk_namespace;
level = level->level_chain)
if (!lookup_using_namespace (name, &binding, level->using_directives,
scope, flags, spacesp))
@@ -5936,7 +5805,7 @@
struct cp_binding_level *level;
for (level = current_binding_level;
- level && !level->namespace_p;
+ level && level->kind != sk_namespace;
level = level->level_chain)
{
tree class_type;
@@ -5944,7 +5813,7 @@
/* A conversion operator can only be declared in a class
scope. */
- if (level->parm_flag != 2)
+ if (level->kind != sk_class)
continue;
/* Lookup the conversion operator in the class. */
@@ -6034,11 +5903,9 @@
tree t = NULL_TREE;
timevar_push (TV_NAME_LOOKUP);
- b = current_binding_level;
- while (b->parm_flag == 2)
- b = b->level_chain;
+ b = innermost_nonclass_level ();
- if (b->namespace_p)
+ if (b->kind == sk_namespace)
{
t = IDENTIFIER_NAMESPACE_VALUE (name);
@@ -6054,7 +5921,7 @@
if (BINDING_SCOPE (IDENTIFIER_BINDING (name)) == b)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
- if (b->keep == 2)
+ if (b->kind == sk_cleanup)
b = b->level_chain;
else
break;
@@ -6072,7 +5939,8 @@
register tree t = NULL_TREE;
timevar_push (TV_NAME_LOOKUP);
- my_friendly_assert (! current_binding_level->namespace_p, 980716);
+ my_friendly_assert (current_binding_level->kind != sk_namespace,
+ 980716);
if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
&& REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
@@ -6083,7 +5951,7 @@
if (purpose_member (name, b->type_shadowed))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
REAL_IDENTIFIER_TYPE_VALUE (name));
- if (b->keep == 2)
+ if (b->kind == sk_cleanup)
b = b->level_chain;
else
break;
@@ -6094,6 +5962,19 @@
}
+
+/* A chain of TYPE_DECLs for the builtin types. */
+
+static GTY(()) tree builtin_type_decls;
+
+/* Return a chain of TYPE_DECLs for the builtin types. */
+
+tree
+cxx_builtin_type_decls ()
+{
+ return builtin_type_decls;
+}
+
/* Push the declarations of builtin types into the namespace.
RID_INDEX is the index of the builtin type in the array
RID_POINTERS. NAME is the name used when looking up the builtin
@@ -6121,8 +6002,7 @@
{
tdecl = build_decl (TYPE_DECL, tname, type);
DECL_ARTIFICIAL (tdecl) = 1;
- if (tname)
- SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
+ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
}
if (rname)
{
@@ -6136,6 +6016,12 @@
if (!TYPE_NAME (type))
TYPE_NAME (type) = tdecl;
+
+ if (tdecl)
+ {
+ TREE_CHAIN (tdecl) = builtin_type_decls;
+ builtin_type_decls = tdecl;
+ }
}
/* Record one of the standard Java types.
@@ -6266,7 +6152,7 @@
my_friendly_assert (global_namespace == NULL_TREE, 375);
global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
void_type_node);
- initial_push_namespace_scope (global_namespace);
+ begin_scope (sk_namespace, global_namespace);
current_lang_name = NULL_TREE;
@@ -6504,7 +6390,7 @@
if (current_function_decl)
{
struct cp_binding_level *b = current_binding_level;
- while (b->level_chain->parm_flag == 0)
+ while (b->level_chain->kind != sk_function_parms)
b = b->level_chain;
pushdecl_with_scope (decl, b);
}
@@ -6548,9 +6434,13 @@
if (libname)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
if (EMIT_LLVM)
+ {
llvm_make_decl_llvm(decl, NULL);
+ }
else
+ {
make_decl_rtl (decl, NULL);
+ }
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
@@ -6742,8 +6632,8 @@
/* ISO C++ 9.5.3. Anonymous unions may not have function members. */
if (TYPE_METHODS (t))
- error ("%Han anonymous union cannot have function members",
- &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (t)));
+ error ("%Jan anonymous union cannot have function members",
+ TYPE_MAIN_DECL (t));
/* Anonymous aggregates cannot have fields with ctors, dtors or complex
assignment operators (because they cannot have these methods themselves).
@@ -7076,8 +6966,7 @@
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
- warning ("%Hinline function '%D' given attribute noinline",
- &DECL_SOURCE_LOCATION (decl), decl);
+ warning ("%Jinline function '%D' given attribute noinline", decl, decl);
if (context && COMPLETE_TYPE_P (complete_type (context)))
{
@@ -7228,14 +7117,18 @@
DECL_INITIAL (decl) = NULL_TREE;
}
-/* Handle initialization of references.
- These three arguments are from `cp_finish_decl', and have the
- same meaning here that they do there.
+/* Handle initialization of references. DECL, TYPE, and INIT have the
+ same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry,
+ but will be set to a new CLEANUP_STMT if a temporary is created
+ that must be destroeyd subsequently.
+
+ Returns an initializer expression to use to initialize DECL, or
+ NULL if the initialization can be performed statically.
Quotes on semantics can be found in ARM 8.4.3. */
static tree
-grok_reference_init (tree decl, tree type, tree init)
+grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
{
tree tmp;
@@ -7272,7 +7165,7 @@
DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized
first. */
- tmp = initialize_reference (type, init, decl);
+ tmp = initialize_reference (type, init, decl, cleanup);
if (tmp == error_mark_node)
return NULL_TREE;
@@ -7442,8 +7335,8 @@
TREE_PUBLIC (decl) = 0;
DECL_COMMON (decl) = 0;
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
- warning ("%H you can work around this by removing the initializer",
- &DECL_SOURCE_LOCATION (decl));
+ warning ("%J you can work around this by removing the initializer",
+ decl);
}
}
}
@@ -7692,13 +7585,14 @@
}
/* Verify INIT (the initializer for DECL), and record the
- initialization in DECL_INITIAL, if appropriate.
+ initialization in DECL_INITIAL, if appropriate. CLEANUP is as for
+ grok_reference_init.
If the return value is non-NULL, it is an expression that must be
evaluated dynamically to initialize DECL. */
static tree
-check_initializer (tree decl, tree init, int flags)
+check_initializer (tree decl, tree init, int flags, tree *cleanup)
{
tree type = TREE_TYPE (decl);
@@ -7748,7 +7642,7 @@
init = NULL_TREE;
}
else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)
- init = grok_reference_init (decl, type, init);
+ init = grok_reference_init (decl, type, init, cleanup);
else if (init)
{
if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))
@@ -7951,7 +7845,7 @@
return;
}
- if (current_binding_level->is_for_scope)
+ if (current_binding_level->kind == sk_for)
{
struct cp_binding_level *outer
= current_binding_level->level_chain;
@@ -7974,7 +7868,7 @@
{
BINDING_VALUE (outer_binding)
= DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding));
- current_binding_level->is_for_scope = 0;
+ current_binding_level->kind = sk_block;
}
}
timevar_pop (TV_NAME_LOOKUP);
@@ -8055,8 +7949,9 @@
void
cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
{
- register tree type;
+ tree type;
tree ttype = NULL_TREE;
+ tree cleanup;
const char *asmspec = NULL;
int was_readonly = 0;
@@ -8069,6 +7964,9 @@
my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
+ /* Assume no cleanup is required. */
+ cleanup = NULL_TREE;
+
/* If a name was specified, get the string. */
if (global_scope_p (current_binding_level))
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
@@ -8184,7 +8082,7 @@
is *not* defined. */
&& (!DECL_EXTERNAL (decl) || init))
{
- init = check_initializer (decl, init, flags);
+ init = check_initializer (decl, init, flags, &cleanup);
/* Thread-local storage cannot be dynamically initialized. */
if (DECL_THREAD_LOCAL (decl) && init)
{
@@ -8263,8 +8161,7 @@
if (DECL_FUNCTION_SCOPE_P (decl))
{
/* This is a local declaration. */
- if (doing_semantic_analysis_p ())
- maybe_inject_for_scope_var (decl);
+ maybe_inject_for_scope_var (decl);
/* Initialize the local variable. */
if (processing_template_decl)
{
@@ -8300,6 +8197,11 @@
}
}
+ /* If a CLEANUP_STMT was created to destroy a temporary bound to a
+ reference, insert it in the statement-tree now. */
+ if (cleanup)
+ add_stmt (cleanup);
+
finish_end:
if (was_readonly)
@@ -11173,8 +11075,7 @@
{
decl = build_decl (TYPE_DECL, declarator, type);
if (in_namespace || ctype)
- error ("%Htypedef name may not be a nested-name-specifier",
- &DECL_SOURCE_LOCATION (decl));
+ error ("%Jtypedef name may not be a nested-name-specifier", decl);
if (!current_function_decl)
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
}
@@ -11220,8 +11121,8 @@
if (ctype == NULL_TREE)
{
if (TREE_CODE (type) != METHOD_TYPE)
- error ("%Hinvalid type qualifier for non-member function type",
- &DECL_SOURCE_LOCATION (decl));
+ error ("%Jinvalid type qualifier for non-member function type",
+ decl);
else
ctype = TYPE_METHOD_BASETYPE (type);
}
@@ -13057,8 +12958,7 @@
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
{
error ("multiple definition of `%#T'", enumtype);
- error ("%Hprevious definition here",
- &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)));
+ error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
/* Clear out TYPE_VALUES, and start again. */
TYPE_VALUES (enumtype) = NULL_TREE;
}
@@ -13500,8 +13400,7 @@
if (DECL_DECLARED_INLINE_P (decl1)
&& lookup_attribute ("noinline", attrs))
- warning ("%Hinline function '%D' given attribute noinline",
- &DECL_SOURCE_LOCATION (decl1), decl1);
+ warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
/* This is a constructor, we must ensure that any default args
@@ -13595,7 +13494,7 @@
CFUN set up, and our per-function variables initialized.
FIXME factor out the non-RTL stuff. */
bl = current_binding_level;
- init_function_start (decl1);
+ allocate_struct_function (decl1);
current_binding_level = bl;
/* Even though we're inside a function body, we still don't want to
@@ -13744,8 +13643,7 @@
DECL_INTERFACE_KNOWN (decl1) = 1;
}
- pushlevel (0);
- current_binding_level->parm_flag = 1;
+ begin_scope (sk_function_parms, decl1);
++function_depth;
@@ -13866,9 +13764,6 @@
f->bindings = NULL;
f->x_local_names = NULL;
- /* When we get back here again, we will be expanding. */
- f->x_expanding_p = 1;
-
/* If we've already decided that we cannot inline this function, we
must remember that fact when we actually go to expand the
function. */
@@ -14000,7 +13895,7 @@
/* Always keep the BLOCK node associated with the outermost pair of
curly braces of a function. These are needed for correct
operation of dwarfout.c. */
- keep_next_level (1);
+ keep_next_level (true);
stmt = begin_compound_stmt (/*has_no_scope=*/false);
COMPOUND_STMT_BODY_BLOCK (stmt) = 1;
@@ -14120,7 +14015,7 @@
/* If the current binding level isn't the outermost binding level
for this function, either there is a bug, or we have experienced
syntax errors and the statement tree is malformed. */
- if (current_binding_level->parm_flag != 1)
+ if (current_binding_level->kind != sk_function_parms)
{
/* Make sure we have already experienced errors. */
if (errorcount == 0)
@@ -14130,9 +14025,9 @@
levels. */
DECL_SAVED_TREE (fndecl) = build_stmt (COMPOUND_STMT, NULL_TREE);
- while (current_binding_level->parm_flag != 1)
+ while (current_binding_level->kind != sk_function_parms)
{
- if (current_binding_level->parm_flag == 2)
+ if (current_binding_level->kind == sk_class)
pop_nested_class ();
else
poplevel (0, 0, 0);
@@ -14140,6 +14035,10 @@
}
poplevel (1, 0, 1);
+ /* Statements should always be full-expressions at the outermost set
+ of curly braces for a function. */
+ my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
+
/* Set up the named return value optimization, if we can. Here, we
eliminate the copy from the nrv into the RESULT_DECL and any cleanup
for the nrv. genrtl_start_function and declare_return_variable
@@ -14152,7 +14051,7 @@
if (r != error_mark_node
/* This is only worth doing for fns that return in memory--and
simpler, since we don't have to worry about promoted modes. */
- && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
+ && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl)
/* Only allow this for variables declared in the outer scope of
the function so we know that their lifetime always ends with a
return; see g++.dg/opt/nrv6.C. We could be more flexible if
@@ -14210,13 +14109,11 @@
inline function, as we might never be compiled separately. */
&& (DECL_INLINE (fndecl) || processing_template_decl))
warning ("no return statement in function returning non-void");
-
- /* Clear out memory we no longer need. */
- free_after_parsing (cfun);
- /* Since we never call rest_of_compilation, we never clear
- CFUN. Do so explicitly. */
- free_after_compilation (cfun);
+
+ /* We're leaving the context of this function, so zap cfun. It's still in
+ DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation. */
cfun = NULL;
+ current_function_decl = NULL;
/* If this is an in-class inline definition, we may have to pop the
bindings for the template parameters that we added in
@@ -14323,8 +14220,7 @@
cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
/* Make a place for the parms */
- pushlevel (0);
- current_binding_level->parm_flag = 1;
+ begin_scope (sk_function_parms, fndecl);
DECL_IN_AGGR_P (fndecl) = 1;
return fndecl;
@@ -14528,13 +14424,34 @@
= ggc_alloc_cleared (sizeof (struct language_function));
f->language = p;
- /* It takes an explicit call to expand_body to generate RTL for a
- function. */
- expanding_p = 0;
-
/* Whenever we start a new function, we destroy temporaries in the
usual way. */
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+
+ if (f->decl)
+ {
+ tree fn = f->decl;
+
+ current_function_is_thunk = DECL_THUNK_P (fn);
+
+ if (DECL_SAVED_FUNCTION_DATA (fn))
+ {
+ /* If we already parsed this function, and we're just expanding it
+ now, restore saved state. */
+ *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
+
+ /* If we decided that we didn't want to inline this function,
+ make sure the back-end knows that. */
+ if (!current_function_cannot_inline)
+ current_function_cannot_inline = cp_function_chain->cannot_inline;
+
+ /* We don't need the saved data anymore. Unless this is an inline
+ function; we need the named return value info for
+ cp_copy_res_decl_for_inlining. */
+ if (! DECL_INLINE (fn))
+ DECL_SAVED_FUNCTION_DATA (fn) = NULL;
+ }
+ }
}
/* Free the language-specific parts of F, now that we've finished
Index: gcc-3.4/gcc/cp/decl2.c
diff -u gcc-3.4/gcc/cp/decl2.c:1.2 gcc-3.4/gcc/cp/decl2.c:1.3
--- gcc-3.4/gcc/cp/decl2.c:1.2 Thu Jan 8 17:05:28 2004
+++ gcc-3.4/gcc/cp/decl2.c Thu Feb 5 10:05:46 2004
@@ -467,8 +467,8 @@
expr = build_array_ref (array_expr, index_exp);
}
if (processing_template_decl && expr != error_mark_node)
- return build_min (ARRAY_REF, TREE_TYPE (expr), orig_array_expr,
- orig_index_exp);
+ return build_min_non_dep (ARRAY_REF, expr,
+ orig_array_expr, orig_index_exp);
return expr;
}
@@ -1625,6 +1625,17 @@
}
}
+/* Return true if VAR has already been provided to the back end; in that
+ case VAR should not be modified further by the front end. */
+static bool
+var_finalized_p (tree var)
+{
+ if (flag_unit_at_a_time)
+ return cgraph_varpool_node (var)->finalized;
+ else
+ return TREE_ASM_WRITTEN (var);
+}
+
/* If necessary, write out the vtables for the dynamic class CTYPE.
Returns true if any vtables were emitted. */
@@ -1638,7 +1649,7 @@
/* If the vtables for this class have already been emitted there is
nothing more to do. */
primary_vtbl = CLASSTYPE_VTABLES (ctype);
- if (TREE_ASM_WRITTEN (primary_vtbl))
+ if (var_finalized_p (primary_vtbl))
return false;
/* Ignore dummy vtables made by get_vtable_decl. */
if (TREE_TYPE (primary_vtbl) == void_type_node)
@@ -2462,7 +2473,7 @@
tree v;
for (v = vars; v; v = TREE_CHAIN (v))
- if (! TREE_ASM_WRITTEN (TREE_VALUE (v)))
+ if (!var_finalized_p (TREE_VALUE (v)))
rest_of_decl_compilation (TREE_VALUE (v), 0, 1, 1);
}
@@ -2563,63 +2574,30 @@
return 0;
}
-/* Callgraph code does not understand the member pointers. Mark the methods
- referenced as used. */
-static tree
-mark_member_pointers_and_eh_handlers (tree *tp,
- int *walk_subtrees,
- void *data ATTRIBUTE_UNUSED)
+/* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR. It is supposed to mark
+ decls referenced from frontend specific constructs; it will be called
+ only for language-specific tree nodes.
+
+ Here we must deal with member pointers. */
+
+tree
+cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ tree from ATTRIBUTE_UNUSED)
{
- /* Avoid useless walking of complex type and declaration nodes. */
- if (TYPE_P (*tp) || DECL_P (*tp))
- {
- *walk_subtrees = 0;
- return 0;
- }
- switch (TREE_CODE (*tp))
+ tree t = *tp;
+
+ switch (TREE_CODE (t))
{
case PTRMEM_CST:
- if (TYPE_PTRMEMFUNC_P (TREE_TYPE (*tp)))
- cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (*tp)), 1);
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+ cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (t)));
break;
- /* EH handlers will emit EH tables referencing typeinfo. */
- case HANDLER:
- if (HANDLER_TYPE (*tp))
- {
- tree tinfo = eh_type_info (HANDLER_TYPE (*tp));
-
- cgraph_varpool_mark_needed_node (cgraph_varpool_node (tinfo));
- }
- break;
-
- case EH_SPEC_BLOCK:
- {
- tree type;
-
- for (type = EH_SPEC_RAISES ((*tp)); type;
- type = TREE_CHAIN (type))
- {
- tree tinfo = eh_type_info (TREE_VALUE (type));
-
- cgraph_varpool_mark_needed_node (cgraph_varpool_node (tinfo));
- }
- }
- break;
default:
break;
}
- return 0;
-}
-/* Called via LANGHOOK_CALLGRAPH_LOWER_FUNCTION. It is supposed to lower
- frontend specific constructs that would otherwise confuse the middle end. */
-void
-lower_function (tree fn)
-{
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
- mark_member_pointers_and_eh_handlers,
- NULL);
+ return NULL;
}
/* This routine is called from the last rule in yyparse ().
@@ -2737,12 +2715,12 @@
them to the beginning of the array, then get rid of the
leftovers. */
n_new = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) - n_old;
- memmove (&VARRAY_TREE (unemitted_tinfo_decls, 0),
- &VARRAY_TREE (unemitted_tinfo_decls, n_old),
- n_new * sizeof (tree));
+ if (n_new)
+ memmove (&VARRAY_TREE (unemitted_tinfo_decls, 0),
+ &VARRAY_TREE (unemitted_tinfo_decls, n_old),
+ n_new * sizeof (tree));
memset (&VARRAY_TREE (unemitted_tinfo_decls, n_new),
- 0,
- n_old * sizeof (tree));
+ 0, n_old * sizeof (tree));
VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) = n_new;
/* The list of objects with static storage duration is built up
@@ -2885,7 +2863,7 @@
for (i = 0; i < pending_statics_used; ++i)
{
tree decl = VARRAY_TREE (pending_statics, i);
- if (TREE_ASM_WRITTEN (decl))
+ if (var_finalized_p (decl))
continue;
import_export_decl (decl);
if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
@@ -2895,6 +2873,9 @@
&& wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0),
pending_statics_used))
reconsider = true;
+
+ if (cgraph_assemble_pending_functions ())
+ reconsider = true;
}
while (reconsider);
@@ -3039,7 +3020,7 @@
expr = build_function_call (fn, args);
if (processing_template_decl && expr != error_mark_node)
- return build_min (CALL_EXPR, TREE_TYPE (expr), orig_fn, orig_args);
+ return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args);
return expr;
}
@@ -3253,10 +3234,8 @@
if (flags & LOOKUP_COMPLAIN)
{
error ("`%D' denotes an ambiguous type",name);
- error ("%H first type here",
- &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (BINDING_TYPE (old))));
- error ("%H other type here",
- &DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)));
+ error ("%J first type here", TYPE_MAIN_DECL (BINDING_TYPE (old)));
+ error ("%J other type here", TYPE_MAIN_DECL (type));
}
}
return old;
@@ -3509,6 +3488,8 @@
/* We must find only functions, or exactly one non-function. */
if (!k->functions)
k->functions = fn;
+ else if (fn == k->functions)
+ ;
else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
k->functions = build_overload (fn, k->functions);
else
Index: gcc-3.4/gcc/cp/method.c
diff -u gcc-3.4/gcc/cp/method.c:1.2 gcc-3.4/gcc/cp/method.c:1.3
--- gcc-3.4/gcc/cp/method.c:1.2 Thu Jan 8 17:05:28 2004
+++ gcc-3.4/gcc/cp/method.c Thu Feb 5 10:05:46 2004
@@ -431,6 +431,7 @@
tree x = copy_node (a);
TREE_CHAIN (x) = t;
DECL_CONTEXT (x) = thunk_fndecl;
+ SET_DECL_RTL (x, NULL_RTX);
t = x;
}
a = nreverse (t);
Index: gcc-3.4/gcc/cp/pt.c
diff -u gcc-3.4/gcc/cp/pt.c:1.2 gcc-3.4/gcc/cp/pt.c:1.3
--- gcc-3.4/gcc/cp/pt.c:1.2 Thu Jan 8 17:05:28 2004
+++ gcc-3.4/gcc/cp/pt.c Thu Feb 5 10:05:47 2004
@@ -94,7 +94,7 @@
static int resolve_overloaded_unification (tree, tree, tree, tree,
unification_kind_t, int);
static int try_one_overload (tree, tree, tree, tree, tree,
- unification_kind_t, int);
+ unification_kind_t, int, bool);
static int unify (tree, tree, tree, tree, int);
static void add_pending_template (tree);
static void reopen_tinst_level (tree);
@@ -353,7 +353,8 @@
parms, current_template_parms);
TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
- pushlevel (0);
+ begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec,
+ NULL);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
@@ -610,7 +611,7 @@
pushtag contains special code to call pushdecl_with_scope on the
TEMPLATE_DECL for S2. */
- begin_scope (sk_template_parms);
+ begin_scope (sk_template_parms, NULL);
++processing_template_decl;
++processing_template_parmlist;
note_template_header (0);
@@ -654,7 +655,7 @@
void
begin_specialization (void)
{
- begin_scope (sk_template_spec);
+ begin_scope (sk_template_spec, NULL);
note_template_header (1);
check_specialization_scope ();
}
@@ -2947,8 +2948,7 @@
A template-parameter may not be given default arguments
by two different declarations in the same scope. */
error ("redefinition of default argument for `%#D'", parm);
- error ("%H original definition appeared here",
- &DECL_SOURCE_LOCATION (tmpl_parm));
+ error ("%J original definition appeared here", tmpl_parm);
return;
}
@@ -3210,9 +3210,12 @@
tree type_referred_to = TREE_TYPE (type);
/* If this expression already has reference type, get the
- underling object. */
+ underlying object. */
if (TREE_CODE (expr_type) == REFERENCE_TYPE)
{
+ if (TREE_CODE (expr) == NOP_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ STRIP_NOPS (expr);
my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
expr = TREE_OPERAND (expr, 0);
expr_type = TREE_TYPE (expr);
@@ -3266,7 +3269,7 @@
}
cxx_mark_addressable (expr);
- return build1 (ADDR_EXPR, type, expr);
+ return build_nop (type, build_address (expr));
}
break;
@@ -3852,7 +3855,8 @@
return error_mark_node;
my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
- if (fns == NULL_TREE)
+ if (fns == NULL_TREE
+ || TREE_CODE (fns) == FUNCTION_DECL)
{
error ("non-template used as template");
return error_mark_node;
@@ -4998,6 +5002,8 @@
DECL_USE_TEMPLATE (tmpl) = 0;
DECL_TEMPLATE_INFO (tmpl) = NULL_TREE;
CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0;
+ CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
/* Inject this template into the global scope. */
friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
@@ -5251,12 +5257,14 @@
if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
/* Unfortunately, lookup_template_class sets
CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
- instantiation (i.e., for the type of a member template
- class nested within a template class.) This behavior is
- required for maybe_process_partial_specialization to work
- correctly, but is not accurate in this case; the TAG is not
- an instantiation of anything. (The corresponding
- TEMPLATE_DECL is an instantiation, but the TYPE is not.) */
+ instantiation (i.e., for the type of a member
+ template class nested within a template class.)
+ This behavior is required for
+ maybe_process_partial_specialization to work
+ correctly, but is not accurate in this case;
+ the TAG is not an instantiation of anything.
+ (The corresponding TEMPLATE_DECL is an
+ instantiation, but the TYPE is not.) */
CLASSTYPE_USE_TEMPLATE (newtag) = 0;
/* Now, we call pushtag to put this NEWTAG into the scope of
@@ -5273,8 +5281,13 @@
|| DECL_FUNCTION_TEMPLATE_P (t))
{
/* Build new TYPE_METHODS. */
-
- tree r = tsubst (t, args, tf_error, NULL_TREE);
+ tree r;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl++;
+ r = tsubst (t, args, tf_error, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ processing_template_decl--;
set_current_access_from_decl (r);
grok_special_member_properties (r);
finish_member_declaration (r);
@@ -7089,7 +7102,17 @@
my_friendly_assert (!dependent_type_p (scope), 20030729);
if (!BASELINK_P (name) && !DECL_P (expr))
- expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+ {
+ expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+ if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
+ ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
+ {
+ if (complain & tf_error)
+ error ("`%E' names a type, but a non-type is expected",
+ qualified_id);
+ return error_mark_node;
+ }
+ }
if (DECL_P (expr))
check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
@@ -7303,7 +7326,6 @@
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
@@ -7548,7 +7570,8 @@
scope = tsubst_expr (scope, args, complain, in_decl);
decl = lookup_qualified_name (scope, name,
- /*is_type_p=*/0, /*complain=*/false);
+ /*is_type_p=*/false,
+ /*complain=*/false);
if (decl == error_mark_node)
qualified_name_lookup_error (scope, name);
else
@@ -7973,6 +7996,8 @@
else
op1 = tsubst_non_call_postfix_expression (op1, args, complain,
in_decl);
+ if (TREE_CODE (op1) == LABEL_DECL)
+ return finish_label_address_expr (DECL_NAME (op1));
return build_x_unary_op (ADDR_EXPR, op1);
case PLUS_EXPR:
@@ -7984,7 +8009,6 @@
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
@@ -8046,10 +8070,10 @@
op1 = RECUR (op1);
--skip_evaluation;
}
- if (TREE_CODE (t) == SIZEOF_EXPR)
- return finish_sizeof (op1);
+ if (TYPE_P (op1))
+ return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
else
- return finish_alignof (op1);
+ return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
case MODOP_EXPR:
return build_x_modify_expr
@@ -8091,18 +8115,9 @@
bool koenig_p;
function = TREE_OPERAND (t, 0);
- /* To determine whether or not we should perform Koenig lookup
- we must look at the form of the FUNCTION. */
- koenig_p = !(/* Koenig lookup does not apply to qualified
- names. */
- TREE_CODE (function) == SCOPE_REF
- /* Or to references to members of classes. */
- || TREE_CODE (function) == COMPONENT_REF
- /* If it is a FUNCTION_DECL or a baselink, then
- the name was already resolved when the
- template was parsed. */
- || TREE_CODE (function) == FUNCTION_DECL
- || TREE_CODE (function) == BASELINK);
+ /* When we parsed the expression, we determined whether or
+ not Koenig lookup should be performed. */
+ koenig_p = KOENIG_LOOKUP_P (t);
if (TREE_CODE (function) == SCOPE_REF)
{
qualified_p = true;
@@ -8118,23 +8133,22 @@
function = tsubst_copy_and_build (function, args, complain,
in_decl,
!qualified_p);
+ if (BASELINK_P (function))
+ qualified_p = true;
}
call_args = RECUR (TREE_OPERAND (t, 1));
- if (BASELINK_P (function))
- qualified_p = 1;
-
if (koenig_p
- && TREE_CODE (function) != TEMPLATE_ID_EXPR
&& (is_overloaded_fn (function)
|| DECL_P (function)
|| TREE_CODE (function) == IDENTIFIER_NODE))
+ function = perform_koenig_lookup (function, call_args);
+
+ if (TREE_CODE (function) == IDENTIFIER_NODE)
{
- if (call_args)
- function = perform_koenig_lookup (function, call_args);
- else if (TREE_CODE (function) == IDENTIFIER_NODE)
- function = unqualified_name_lookup_error (function);
+ unqualified_name_lookup_error (function);
+ return error_mark_node;
}
/* Remember that there was a reference to this entity. */
@@ -8152,7 +8166,8 @@
call_args, NULL_TREE,
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
return finish_call_expr (function, call_args,
- /*disallow_virtual=*/qualified_p);
+ /*disallow_virtual=*/qualified_p,
+ koenig_p);
}
case COND_EXPR:
@@ -8232,7 +8247,8 @@
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, /*complain=*/false);
+ /*is_type_p=*/false,
+ /*complain=*/false);
if (BASELINK_P (member))
BASELINK_FUNCTIONS (member)
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
@@ -8918,9 +8934,15 @@
{
tree tempargs = copy_node (targs);
int good = 0;
+ bool addr_p;
if (TREE_CODE (arg) == ADDR_EXPR)
- arg = TREE_OPERAND (arg, 0);
+ {
+ arg = TREE_OPERAND (arg, 0);
+ addr_p = true;
+ }
+ else
+ addr_p = false;
if (TREE_CODE (arg) == COMPONENT_REF)
/* Handle `&x' where `x' is some static or non-static member
@@ -8956,10 +8978,8 @@
if (subargs)
{
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
- if (TREE_CODE (elem) == METHOD_TYPE)
- elem = build_ptrmemfunc_type (build_pointer_type (elem));
- good += try_one_overload (tparms, targs, tempargs, parm, elem,
- strict, sub_strict);
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ elem, strict, sub_strict, addr_p);
}
}
}
@@ -8967,14 +8987,9 @@
|| TREE_CODE (arg) == FUNCTION_DECL)
{
for (; arg; arg = OVL_NEXT (arg))
- {
- tree type = TREE_TYPE (OVL_CURRENT (arg));
- if (TREE_CODE (type) == METHOD_TYPE)
- type = build_ptrmemfunc_type (build_pointer_type (type));
- good += try_one_overload (tparms, targs, tempargs, parm,
- type,
- strict, sub_strict);
- }
+ good += try_one_overload (tparms, targs, tempargs, parm,
+ TREE_TYPE (OVL_CURRENT (arg)),
+ strict, sub_strict, addr_p);
}
else
abort ();
@@ -9003,6 +9018,9 @@
/* Subroutine of resolve_overloaded_unification; does deduction for a single
overload. Fills TARGS with any deduced arguments, or error_mark_node if
different overloads deduce different arguments for a given parm.
+ ADDR_P is true if the expression for which deduction is being
+ performed was of the form "& fn" rather than simply "fn".
+
Returns 1 on success. */
static int
@@ -9012,7 +9030,8 @@
tree parm,
tree arg,
unification_kind_t strict,
- int sub_strict)
+ int sub_strict,
+ bool addr_p)
{
int nargs;
tree tempargs;
@@ -9028,6 +9047,11 @@
if (uses_template_parms (arg))
return 1;
+ if (TREE_CODE (arg) == METHOD_TYPE)
+ arg = build_ptrmemfunc_type (build_pointer_type (arg));
+ else if (addr_p)
+ arg = build_pointer_type (arg);
+
sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
/* We don't copy orig_targs for this because if we have already deduced
@@ -10594,7 +10618,14 @@
details. */
DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl);
COPY_DECL_ASSEMBLER_NAME (decl, new_decl);
- COPY_DECL_RTL (decl, new_decl);
+ if (EMIT_LLVM)
+ {
+ COPY_DECL_LLVM (decl, new_decl);
+ }
+ else
+ {
+ COPY_DECL_RTL (decl, new_decl);
+ }
DECL_USE_TEMPLATE (new_decl) = DECL_USE_TEMPLATE (decl);
/* Call duplicate decls to merge the old and new declarations. */
@@ -10724,10 +10755,14 @@
timevar_push (TV_PARSE);
- /* We may be in the middle of deferred access check. Disable
- it now. */
+ /* We may be in the middle of deferred access check. Disable it now. */
push_deferring_access_checks (dk_no_deferred);
+ /* Our caller does not expect collection to happen, which it might if
+ we decide to compile the function to rtl now. Arrange for a new
+ gc context to be created if so. */
+ function_depth++;
+
/* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
for the instantiation. */
td = template_for_substitution (d);
@@ -10972,6 +11007,7 @@
input_location = saved_loc;
pop_deferring_access_checks ();
pop_tinst_level ();
+ function_depth--;
timevar_pop (TV_PARSE);
@@ -11333,7 +11369,8 @@
/* ... or any of the template arguments is a dependent type or
an expression that is type-dependent or value-dependent. */
else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
- && any_dependent_template_arguments_p (CLASSTYPE_TI_ARGS (type)))
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
return true;
/* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
@@ -11805,6 +11842,11 @@
types. */
if (TREE_CODE (expr) == OVERLOAD)
return expr;
+ /* Preserve string constants; conversions from string constants to
+ "char *" are allowed, even though normally a "const char *"
+ cannot be used to initialize a "char *". */
+ if (TREE_CODE (expr) == STRING_CST)
+ return expr;
if (TREE_CODE (expr) == COND_EXPR)
return build (COND_EXPR,
@@ -11812,7 +11854,8 @@
TREE_OPERAND (expr, 0),
build_non_dependent_expr (TREE_OPERAND (expr, 1)),
build_non_dependent_expr (TREE_OPERAND (expr, 2)));
- if (TREE_CODE (expr) == COMPOUND_EXPR)
+ if (TREE_CODE (expr) == COMPOUND_EXPR
+ && !COMPOUND_EXPR_OVERLOADED (expr))
return build (COMPOUND_EXPR,
TREE_TYPE (expr),
TREE_OPERAND (expr, 0),
Index: gcc-3.4/gcc/cp/rtti.c
diff -u gcc-3.4/gcc/cp/rtti.c:1.2 gcc-3.4/gcc/cp/rtti.c:1.3
--- gcc-3.4/gcc/cp/rtti.c:1.2 Fri Jan 9 10:54:32 2004
+++ gcc-3.4/gcc/cp/rtti.c Thu Feb 5 10:05:47 2004
@@ -358,8 +358,9 @@
TREE_READONLY (d) = 1;
TREE_STATIC (d) = 1;
DECL_EXTERNAL (d) = 1;
- SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1;
+ TREE_PUBLIC (d) = 1;
+ SET_DECL_ASSEMBLER_NAME (d, name);
pushdecl_top_level_and_finish (d, NULL_TREE);
@@ -373,6 +374,10 @@
my_friendly_assert (unemitted_tinfo_decls != 0, 20030312);
VARRAY_PUSH_TREE (unemitted_tinfo_decls, d);
+ /*
+ * LLVM_TODO:
+ * I don't know if this should be here or not.
+ */
if (is_in_anonymous_namespace(TYPE_CONTEXT(type)))
TREE_PUBLIC(d) = 0;
}
@@ -655,6 +660,7 @@
(NULL_TREE, ptrdiff_type_node, void_list_node))));
tmp = build_function_type (ptr_type_node, tmp);
dcast_fn = build_library_fn_ptr (name, tmp);
+ DECL_IS_PURE (dcast_fn) = 1;
pop_nested_namespace (ns);
dynamic_cast_node = dcast_fn;
}
@@ -689,7 +695,12 @@
return error_mark_node;
if (processing_template_decl)
- return build_min (DYNAMIC_CAST_EXPR, type, expr);
+ {
+ expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
+ TREE_SIDE_EFFECTS (expr) = 1;
+
+ return expr;
+ }
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
Index: gcc-3.4/gcc/cp/semantics.c
diff -u gcc-3.4/gcc/cp/semantics.c:1.2 gcc-3.4/gcc/cp/semantics.c:1.3
--- gcc-3.4/gcc/cp/semantics.c:1.2 Thu Jan 8 17:05:28 2004
+++ gcc-3.4/gcc/cp/semantics.c Thu Feb 5 10:05:47 2004
@@ -61,9 +61,6 @@
static void genrtl_eh_spec_block (tree);
static void genrtl_handler (tree);
static void cp_expand_stmt (tree);
-static struct llvm_function *genrtl_start_function (tree);
-static void genrtl_finish_function (struct llvm_function *, tree);
-static tree clear_decl_rtl (tree *, int *, void *);
/* Finish processing the COND, the SUBSTMT condition for STMT. */
@@ -364,7 +361,7 @@
{
if (!processing_template_decl)
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
- begin_scope (sk);
+ begin_scope (sk, NULL);
}
}
@@ -380,13 +377,17 @@
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
-
- if (TREE_CODE (destination) != LABEL_DECL)
- /* We don't inline calls to functions with computed gotos.
- Those functions are typically up to some funny business,
- and may be depending on the labels being at particular
- addresses, or some such. */
- DECL_UNINLINABLE (current_function_decl) = 1;
+ else
+ {
+ /* The DESTINATION is being used as an rvalue. */
+ if (!processing_template_decl)
+ destination = decay_conversion (destination);
+ /* We don't inline calls to functions with computed gotos.
+ Those functions are typically up to some funny business,
+ and may be depending on the labels being at particular
+ addresses, or some such. */
+ DECL_UNINLINABLE (current_function_decl) = 1;
+ }
check_goto (destination);
@@ -1004,7 +1005,7 @@
statement-expression. But, if it's a statement-expression with
a scopeless block, there's nothing to keep, and we don't want
to accidentally keep a block *inside* the scopeless block. */
- keep_next_level (0);
+ keep_next_level (false);
return r;
}
@@ -1408,7 +1409,7 @@
last_expr_type = NULL_TREE;
- keep_next_level (1);
+ keep_next_level (true);
return last_tree;
}
@@ -1534,8 +1535,9 @@
}
/* Perform Koenig lookup. FN is the postfix-expression representing
- the call; ARGS are the arguments to the call. Returns the
- functions to be considered by overload resolution. */
+ the function (or functions) to call; ARGS are the arguments to the
+ call. Returns the functions to be considered by overload
+ resolution. */
tree
perform_koenig_lookup (tree fn, tree args)
@@ -1585,7 +1587,7 @@
Returns code for the call. */
tree
-finish_call_expr (tree fn, tree args, bool disallow_virtual)
+finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
{
tree result;
tree orig_fn;
@@ -1605,7 +1607,11 @@
{
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
- return build_nt (CALL_EXPR, fn, args);
+ {
+ result = build_nt (CALL_EXPR, fn, args);
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ return result;
+ }
if (!BASELINK_P (fn)
&& TREE_CODE (fn) != PSEUDO_DTOR_EXPR
&& TREE_TYPE (fn) != unknown_type_node)
@@ -1618,12 +1624,11 @@
to refer to it. */
if (!BASELINK_P (fn) && is_overloaded_fn (fn))
{
- tree f;
+ tree f = fn;
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- f = get_first_fn (TREE_OPERAND (fn, 0));
- else
- f = get_first_fn (fn);
+ if (TREE_CODE (f) == TEMPLATE_ID_EXPR)
+ f = TREE_OPERAND (f, 0);
+ f = get_first_fn (f);
if (DECL_FUNCTION_MEMBER_P (f))
{
tree type = currently_open_derived_class (DECL_CONTEXT (f));
@@ -1707,7 +1712,10 @@
result = build_function_call (fn, args);
if (processing_template_decl)
- return build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+ {
+ result = build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ }
return result;
}
@@ -2661,26 +2669,6 @@
return type;
}
-/* Compute the value of the `sizeof' operator. */
-
-tree
-finish_sizeof (tree t)
-{
- return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
-}
-
-/* Implement the __alignof keyword: Return the minimum required
- alignment of T, measured in bytes. */
-
-tree
-finish_alignof (tree t)
-{
- if (processing_template_decl)
- return build_min (ALIGNOF_EXPR, size_type_node, t);
-
- return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
-}
-
/* Generate RTL for the statement T, and its substatements, and any
other statements at its nesting level. */
@@ -2859,14 +2847,7 @@
void
expand_body (tree fn)
{
- location_t saved_loc;
tree saved_function;
-#if EMIT_LLVM
- struct llvm_function *LLVMFn;
-#endif
-
- if (flag_unit_at_a_time && !cgraph_global_info_ready)
- abort ();
/* Compute the appropriate object-file linkage for inline
functions. */
@@ -2879,75 +2860,57 @@
we're not planning on emitting it, in case we get a chance to
inline it. */
if (DECL_EXTERNAL (fn))
+ {
return;
+ }
- /* Save the current file name and line number. When we expand the
- body of the function, we'll set INPUT_LOCATION so that
- error-messages come out in the right places. */
- saved_loc = input_location;
+ /* ??? When is this needed? */
saved_function = current_function_decl;
- input_location = DECL_SOURCE_LOCATION (fn);
- current_function_decl = fn;
timevar_push (TV_INTEGRATION);
-
- /* Optimize the body of the function before expanding it. */
optimize_function (fn);
-
timevar_pop (TV_INTEGRATION);
- timevar_push (TV_EXPAND);
-
-#if EMIT_LLVM
- LLVMFn =
-#endif
- genrtl_start_function (fn);
-
- current_function_is_thunk = DECL_THUNK_P (fn);
-
- /* Expand the body. */
-#if EMIT_LLVM
- llvm_expand_stmt(LLVMFn, DECL_SAVED_TREE (fn));
-#else
- expand_stmt (DECL_SAVED_TREE (fn));
-#endif
- /* Statements should always be full-expressions at the outermost set
- of curly braces for a function. */
- my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
-
- /* The outermost statement for a function contains the line number
- recorded when we finished processing the function. */
- input_line = STMT_LINENO (DECL_SAVED_TREE (fn));
+ tree_rest_of_compilation (fn, function_depth > 1);
- /* Generate code for the function. */
- genrtl_finish_function (
-#if EMIT_LLVM
- LLVMFn,
-#endif
- fn);
-
- /* If possible, obliterate the body of the function so that it can
- be garbage collected. */
- if (dump_enabled_p (TDI_all))
- /* Keep the body; we're going to dump it. */
- ;
- else if (DECL_INLINE (fn) && flag_inline_trees)
- /* We might need the body of this function so that we can expand
- it inline somewhere else. */
- ;
- else
- /* We don't need the body; blow it away. */
- DECL_SAVED_TREE (fn) = NULL_TREE;
-
- /* And restore the current source position. */
current_function_decl = saved_function;
- input_location = saved_loc;
- extract_interface_info ();
- timevar_pop (TV_EXPAND);
+ extract_interface_info ();
/* Emit any thunks that should be emitted at the same time as FN. */
emit_associated_thunks (fn);
+
+ /* If this function is marked with the constructor attribute, add it
+ to the list of functions to be called along with constructors
+ from static duration objects. */
+ if (DECL_STATIC_CONSTRUCTOR (fn))
+ static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
+
+ /* If this function is marked with the destructor attribute, add it
+ to the list of functions to be called along with destructors from
+ static duration objects. */
+ if (DECL_STATIC_DESTRUCTOR (fn))
+ static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
+
+ if (DECL_CLONED_FUNCTION_P (fn))
+ {
+ /* If this is a clone, go through the other clones now and mark
+ their parameters used. We have to do that here, as we don't
+ know whether any particular clone will be expanded, and
+ therefore cannot pick one arbitrarily. */
+ tree probe;
+
+ for (probe = TREE_CHAIN (DECL_CLONED_FUNCTION (fn));
+ probe && DECL_CLONED_FUNCTION_P (probe);
+ probe = TREE_CHAIN (probe))
+ {
+ tree parms;
+
+ for (parms = DECL_ARGUMENTS (probe);
+ parms; parms = TREE_CHAIN (parms))
+ TREE_USED (parms) = 1;
+ }
+ }
}
/* Generate RTL for FN. */
@@ -2993,62 +2956,16 @@
if (flag_syntax_only)
return;
- if (flag_unit_at_a_time && cgraph_global_info_ready)
- abort ();
-
- if (flag_unit_at_a_time && !cgraph_global_info_ready)
- {
- if (at_eof)
- {
- /* Compute the appropriate object-file linkage for inline
- functions. */
- if (DECL_DECLARED_INLINE_P (fn))
- import_export_decl (fn);
- cgraph_finalize_function (fn, DECL_SAVED_TREE (fn));
- }
- else
- {
- if (!DECL_EXTERNAL (fn))
- {
- DECL_NOT_REALLY_EXTERN (fn) = 1;
- DECL_EXTERNAL (fn) = 1;
- }
- /* Remember this function. In finish_file we'll decide if
- we actually need to write this function out. */
- defer_fn (fn);
- /* Let the back-end know that this function exists. */
- (*debug_hooks->deferred_inline_function) (fn);
- }
- return;
- }
+ /* Compute the appropriate object-file linkage for inline functions. */
+ if (DECL_DECLARED_INLINE_P (fn))
+ import_export_decl (fn);
+ function_depth++;
- /* If possible, avoid generating RTL for this function. Instead,
- just record it as an inline function, and wait until end-of-file
- to decide whether to write it out or not. */
- if (/* We have to generate RTL if it's not an inline function. */
- (DECL_INLINE (fn) || DECL_COMDAT (fn))
- /* Or if we have to emit code for inline functions anyhow. */
- && !flag_keep_inline_functions
- /* Or if we actually have a reference to the function. */
- && !DECL_NEEDED_P (fn))
- {
- /* Set DECL_EXTERNAL so that assemble_external will be called as
- necessary. We'll clear it again in finish_file. */
- if (!DECL_EXTERNAL (fn))
- {
- DECL_NOT_REALLY_EXTERN (fn) = 1;
- DECL_EXTERNAL (fn) = 1;
- }
- /* Remember this function. In finish_file we'll decide if
- we actually need to write this function out. */
- defer_fn (fn);
- /* Let the back-end know that this function exists. */
- (*debug_hooks->deferred_inline_function) (fn);
- return;
- }
+ /* Expand or defer, at the whim of the compilation unit manager. */
+ cgraph_finalize_function (fn, function_depth > 1);
- expand_body (fn);
+ function_depth--;
}
/* Helper function for walk_tree, used by finish_function to override all
@@ -3076,231 +2993,25 @@
/* Start generating the RTL for FN. */
-static struct llvm_function *
-genrtl_start_function (tree fn)
+void
+cxx_expand_function_start (void)
{
-#if EMIT_LLVM
- struct llvm_function *LLVMFn;
-#endif
-
- /* Tell everybody what function we're processing. */
- current_function_decl = fn;
- /* Get the RTL machinery going for this function. */
- init_function_start (fn);
- /* Let everybody know that we're expanding this function, not doing
- semantic analysis. */
- expanding_p = 1;
-
- /* Even though we're inside a function body, we still don't want to
- call expand_expr to calculate the size of a variable-sized array.
- We haven't necessarily assigned RTL to all variables yet, so it's
- not safe to try to expand expressions involving them. */
- immediate_size_expand = 0;
- cfun->x_dont_save_pending_sizes_p = 1;
-
- /* Let the user know we're compiling this function. */
- announce_function (fn);
-
- /* Initialize the per-function data. */
- my_friendly_assert (!DECL_PENDING_INLINE_P (fn), 20000911);
- if (DECL_SAVED_FUNCTION_DATA (fn))
- {
- /* If we already parsed this function, and we're just expanding it
- now, restore saved state. */
- *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
-
- /* This function is being processed in whole-function mode; we
- already did semantic analysis. */
- cfun->x_whole_function_mode_p = 1;
-
- /* If we decided that we didn't want to inline this function,
- make sure the back-end knows that. */
- if (!current_function_cannot_inline)
- current_function_cannot_inline = cp_function_chain->cannot_inline;
-
- /* We don't need the saved data anymore. Unless this is an inline
- function; we need the named return value info for
- cp_copy_res_decl_for_inlining. */
- if (! DECL_INLINE (fn))
- DECL_SAVED_FUNCTION_DATA (fn) = NULL;
- }
-
- /* Keep track of how many functions we're presently expanding. */
- ++function_depth;
-
-#if EMIT_LLVM
- /* Create a binding level for the parameters. */
- LLVMFn = llvm_expand_function_start (fn, /*parms_have_cleanups=*/0);
-
- /* If the named return value optimization has been applied to this function,
- * set the LLVM value of the named returned value equal to the llvm of the
- * DECL_RESULT.
- */
- if (current_function_return_value)
- COPY_DECL_LLVM (DECL_RESULT (fn), current_function_return_value);
-
- /* If this function is `main'. */
- if (DECL_MAIN_P (fn))
- llvm_expand_main_function (LLVMFn);
-
- return LLVMFn;
-#else
- /* Create a binding level for the parameters. */
- expand_function_start (fn, /*parms_have_cleanups=*/0);
- /* If this function is `main'. */
- if (DECL_MAIN_P (fn))
- expand_main_function ();
-
/* Give our named return value the same RTL as our RESULT_DECL. */
if (current_function_return_value)
- COPY_DECL_RTL (DECL_RESULT (fn), current_function_return_value);
-#endif
+ COPY_DECL_RTL (DECL_RESULT (cfun->decl), current_function_return_value);
}
-/* Finish generating the RTL for FN. */
-
-static void
-genrtl_finish_function (struct llvm_function *LLVMFn, tree fn)
-{
-#if 0
- tree t;
-
- if (write_symbols != NO_DEBUG)
- {
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- tree ttype = target_type (fntype);
- tree parmdecl;
-
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
-
- for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl))
- {
- ttype = target_type (TREE_TYPE (parmdecl));
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
- }
- }
-#endif
-
- /* Clean house because we will need to reorder insns here. */
- do_pending_stack_adjust ();
-
- /* If we have a named return value, we need to force a return so that
- the return register is USEd. */
- if (DECL_NAME (DECL_RESULT (fn)))
- emit_jump (return_label);
-
- /* We hard-wired immediate_size_expand to zero in start_function.
- Expand_function_end will decrement this variable. So, we set the
- variable to one here, so that after the decrement it will remain
- zero. */
- immediate_size_expand = 1;
-
- if (EMIT_LLVM)
- llvm_expand_function_end (LLVMFn, fn, 0);
- else {
- /* Generate rtl for function exit. */
- expand_function_end ();
- }
-
- /* If this is a nested function (like a template instantiation that
- we're compiling in the midst of compiling something else), push a
- new GC context. That will keep local variables on the stack from
- being collected while we're doing the compilation of this
- function. */
- if (function_depth > 1)
- ggc_push_context ();
-
- /* There's no need to defer outputting this function any more; we
- know we want to output it. */
- DECL_DEFER_OUTPUT (fn) = 0;
-
#if EMIT_LLVM
- if (EMIT_CODE_INCREMENTALLY) llvm_function_print(LLVMFn, llvm_out_file);
- cfun = 0;
-#else
- /* Run the optimizers and output the assembler code for this
- function. */
- rest_of_compilation (fn);
-#endif
-
- /* Undo the call to ggc_push_context above. */
- if (function_depth > 1)
- ggc_pop_context ();
-
-#if 0
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- if (ctype && TREE_ASM_WRITTEN (fn))
- note_debug_info_needed (ctype);
-#endif
-
- /* If this function is marked with the constructor attribute, add it
- to the list of functions to be called along with constructors
- from static duration objects. */
- if (DECL_STATIC_CONSTRUCTOR (fn))
- static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
-
- /* If this function is marked with the destructor attribute, add it
- to the list of functions to be called along with destructors from
- static duration objects. */
- if (DECL_STATIC_DESTRUCTOR (fn))
- static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
-
- --function_depth;
-
- /* In C++, we should never be saving RTL for the function. */
- my_friendly_assert (!DECL_SAVED_INSNS (fn), 20010903);
-
-#if !EMIT_LLVM
- /* Since we don't need the RTL for this function anymore, stop
- pointing to it. That's especially important for LABEL_DECLs,
- since you can reach all the instructions in the function from the
- CODE_LABEL stored in the DECL_RTL for the LABEL_DECL. Walk the
- BLOCK-tree, clearing DECL_RTL for LABEL_DECLs and non-static
- local variables. */
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
- clear_decl_rtl,
- NULL);
-
- /* Clear out the RTL for the arguments. */
- for (t = DECL_ARGUMENTS (fn); t; t = TREE_CHAIN (t))
- {
- SET_DECL_RTL (t, NULL_RTX);
- DECL_INCOMING_RTL (t) = NULL_RTX;
- }
-#endif
-
- if (!(flag_inline_trees && DECL_INLINE (fn)))
- /* DECL_INITIAL must remain nonzero so we know this was an
- actual function definition. */
- DECL_INITIAL (fn) = error_mark_node;
-
- /* Let the error reporting routines know that we're outside a
- function. For a nested function, this value is used in
- pop_cp_function_context and then reset via pop_function_context. */
- current_function_decl = NULL_TREE;
-}
-
-/* Clear out the DECL_RTL for the non-static variables in BLOCK and
- its sub-blocks. */
-
-#if !EMIT_LLVM
-static tree
-clear_decl_rtl (tree* tp,
- int* walk_subtrees ATTRIBUTE_UNUSED ,
- void* data ATTRIBUTE_UNUSED )
+/*
+ * Description:
+ * This function is the LLVM version of cxx_expand_function_start().
+ */
+void
+llvm_cxx_expand_function_start (void)
{
- if (nonstatic_local_decl_p (*tp))
- SET_DECL_RTL (*tp, NULL_RTX);
-
- return NULL_TREE;
+ /* Give our named return value the same LLVM as our RESULT_DECL. */
+ if (current_function_return_value)
+ COPY_DECL_LLVM (DECL_RESULT (cfun->decl), current_function_return_value);
}
#endif
Index: gcc-3.4/gcc/cp/typeck.c
diff -u gcc-3.4/gcc/cp/typeck.c:1.2 gcc-3.4/gcc/cp/typeck.c:1.3
--- gcc-3.4/gcc/cp/typeck.c:1.2 Thu Jan 8 17:05:28 2004
+++ gcc-3.4/gcc/cp/typeck.c Thu Feb 5 10:05:47 2004
@@ -902,11 +902,8 @@
if (t1 == t2)
return true;
- /* This should never happen. */
- my_friendly_assert (t1 != error_mark_node, 307);
-
/* Suppress errors caused by previously reported errors */
- if (t2 == error_mark_node)
+ if (t1 == error_mark_node || t2 == error_mark_node)
return false;
my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623);
@@ -1172,23 +1169,33 @@
they fail to match. */
if (!t1 || !t2)
return false;
- if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1)))
+ if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
return false;
}
return true;
}
+/* Process a sizeof or alignof expression where the operand is a
+ type. */
+
tree
-cxx_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
{
enum tree_code type_code;
tree value;
const char *op_name;
my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+ if (type == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min (op, size_type_node, type);
+ {
+ value = build_min (op, size_type_node, type);
+ TREE_READONLY (value) = 1;
+ return value;
+ }
op_name = operator_name_info[(int) op].name;
@@ -1207,30 +1214,46 @@
return value;
}
+/* Process a sizeof or alignof expression where the operand is an
+ expression. */
+
tree
-expr_sizeof (tree e)
+cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
{
+ const char *op_name = operator_name_info[(int) op].name;
+
+ if (e == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min (SIZEOF_EXPR, size_type_node, e);
-
+ {
+ e = build_min (op, size_type_node, e);
+ TREE_SIDE_EFFECTS (e) = 0;
+ TREE_READONLY (e) = 1;
+
+ return e;
+ }
+
if (TREE_CODE (e) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
- error ("sizeof applied to a bit-field");
- if (is_overloaded_fn (e))
{
- pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type");
- return c_sizeof (char_type_node);
+ error ("invalid application of `%s' to a bit-field", op_name);
+ e = char_type_node;
+ }
+ else if (is_overloaded_fn (e))
+ {
+ pedwarn ("ISO C++ forbids applying `%s' to an expression of function type", op_name);
+ e = char_type_node;
}
else if (type_unknown_p (e))
{
cxx_incomplete_type_error (e, TREE_TYPE (e));
- return c_sizeof (char_type_node);
+ e = char_type_node;
}
-
- if (e == error_mark_node)
- return e;
-
- return cxx_sizeof (TREE_TYPE (e));
+ else
+ e = TREE_TYPE (e);
+
+ return cxx_sizeof_or_alignof_type (e, op, true);
}
@@ -1912,8 +1935,8 @@
expr = build_class_member_access_expr (object, member, access_path,
/*preserve_reference=*/false);
if (processing_template_decl && expr != error_mark_node)
- return build_min (COMPONENT_REF, TREE_TYPE (expr), orig_object,
- orig_name);
+ return build_min_non_dep (COMPONENT_REF, expr,
+ orig_object, orig_name);
return expr;
}
@@ -1970,7 +1993,7 @@
rval = build_indirect_ref (expr, errorstring);
if (processing_template_decl && rval != error_mark_node)
- return build_min (INDIRECT_REF, TREE_TYPE (rval), orig_expr);
+ return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
else
return rval;
}
@@ -2515,8 +2538,12 @@
if (!COMPLETE_TYPE_P (complete_type (type)))
{
- error ("parameter type of called function is incomplete");
- parmval = val;
+ if (fndecl)
+ error ("parameter %P of `%D' has incomplete type `%T'",
+ i, fndecl, type);
+ else
+ error ("parameter %P has incomplete type `%T'", i, type);
+ parmval = error_mark_node;
}
else
{
@@ -2620,7 +2647,7 @@
expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
if (processing_template_decl && expr != error_mark_node)
- return build_min (code, TREE_TYPE (expr), orig_arg1, orig_arg2);
+ return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
return expr;
}
@@ -2817,7 +2844,6 @@
break;
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
@@ -3521,7 +3547,8 @@
}
if (processing_template_decl && exp != error_mark_node)
- return build_min (code, TREE_TYPE (exp), orig_expr, NULL_TREE);
+ return build_min_non_dep (code, exp, orig_expr,
+ /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
return exp;
}
@@ -3564,9 +3591,7 @@
if (error_operand_p (t) || !cxx_mark_addressable (t))
return error_mark_node;
- addr = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (t)),
- t);
+ addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
if (staticp (t))
TREE_CONSTANT (addr) = 1;
@@ -3977,7 +4002,7 @@
is an error. */
else if (TREE_CODE (argtype) != FUNCTION_TYPE
&& TREE_CODE (argtype) != METHOD_TYPE
- && !non_cast_lvalue_or_else (arg, "unary `&'"))
+ && !lvalue_or_else (arg, "unary `&'"))
return error_mark_node;
if (argtype != error_mark_node)
@@ -3986,12 +4011,24 @@
{
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)
addr = build_address (arg);
+ else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
+ {
+ tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
+
+ /* We can only get here with a single static member
+ function. */
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (fn),
+ 20030906);
+ mark_used (fn);
+ addr = build_address (fn);
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
+ /* Do not lose object's side effects. */
+ addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
+ TREE_OPERAND (arg, 0), addr);
+ }
else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
error ("attempt to take address of bit-field structure member `%D'",
@@ -4271,8 +4308,8 @@
expr = build_conditional_expr (ifexp, op1, op2);
if (processing_template_decl && expr != error_mark_node)
- return build_min (COND_EXPR, TREE_TYPE (expr),
- orig_ifexp, orig_op1, orig_op2);
+ return build_min_non_dep (COND_EXPR, expr,
+ orig_ifexp, orig_op1, orig_op2);
return expr;
}
@@ -4318,8 +4355,8 @@
result = build_compound_expr (op1, op2);
if (processing_template_decl && result != error_mark_node)
- return build_min (COMPOUND_EXPR, TREE_TYPE (result),
- orig_op1, orig_op2);
+ return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
+
return result;
}
@@ -4376,8 +4413,10 @@
if (processing_template_decl)
{
- tree t = build_min (STATIC_CAST_EXPR, type, expr);
- return t;
+ expr = build_min (STATIC_CAST_EXPR, type, expr);
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (expr) = 1;
+ return expr;
}
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -4411,19 +4450,20 @@
if (TREE_CODE (type) == REFERENCE_TYPE
&& CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (intype)
- && real_non_cast_lvalue_p (expr)
+ && real_lvalue_p (expr)
&& DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT
(TREE_TYPE (type))))
&& at_least_as_qualified_p (TREE_TYPE (type), intype))
{
- /* At this point we have checked all of the conditions except
- that B is not a virtual base class of D. That will be
- checked by build_base_path. */
- tree base = lookup_base (TREE_TYPE (type), intype, ba_any, NULL);
+ /* There is a standard conversion from "D*" to "B*" even if "B"
+ is ambiguous or inaccessible. Therefore, we ask lookup_base
+ to check these conditions. */
+ tree base = lookup_base (TREE_TYPE (type), intype, ba_check, NULL);
- /* Convert from B* to D*. */
+ /* Convert from "B*" to "D*". This function will check that "B"
+ is not a virtual base of "D". */
expr = build_base_path (MINUS_EXPR, build_address (expr),
base, /*nonnull=*/false);
/* Convert the pointer to a reference -- but then remember that
@@ -4467,9 +4507,10 @@
converted to an enumeration type. */
|| (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (intype)))
- /* Really, build_c_cast should defer to this function rather
- than the other way around. */
- return build_c_cast (type, expr);
+ /* Really, build_c_cast should defer to this function rather
+ than the other way around. */
+ return build_c_cast (type, expr);
+
if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
&& CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (TREE_TYPE (intype))
@@ -4481,10 +4522,11 @@
tree base;
check_for_casting_away_constness (intype, type, "static_cast");
- base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
- ba_check | ba_quiet, NULL);
+ base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), ba_check,
+ NULL);
return build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
}
+
if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
{
@@ -4561,6 +4603,11 @@
if (processing_template_decl)
{
tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
@@ -4645,6 +4692,11 @@
if (processing_template_decl)
{
tree t = build_min (CONST_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
@@ -4714,6 +4766,8 @@
{
tree t = build_min (CAST_EXPR, type,
tree_cons (NULL_TREE, value, NULL_TREE));
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
@@ -5677,7 +5731,8 @@
if (fndecl)
savew = warningcount, savee = errorcount;
- rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE);
+ rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE,
+ /*cleanup=*/NULL);
if (fndecl)
{
if (warningcount > savew)
More information about the llvm-commits
mailing list