summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cc/cc1plus/decl2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cc/cc1plus/decl2.c')
-rw-r--r--gnu/usr.bin/cc/cc1plus/decl2.c166
1 files changed, 110 insertions, 56 deletions
diff --git a/gnu/usr.bin/cc/cc1plus/decl2.c b/gnu/usr.bin/cc/cc1plus/decl2.c
index 2b9f8a7..a50b7bc 100644
--- a/gnu/usr.bin/cc/cc1plus/decl2.c
+++ b/gnu/usr.bin/cc/cc1plus/decl2.c
@@ -84,6 +84,11 @@ int flag_no_asm;
int flag_no_builtin;
+/* Nonzero means don't recognize the non-ANSI builtin functions.
+ -ansi sets this. */
+
+int flag_no_nonansi_builtin;
+
/* Nonzero means do some things the same way PCC does. */
int flag_traditional;
@@ -207,6 +212,12 @@ int warn_nonvdtor;
/* Non-zero means warn when a function is declared extern and later inline. */
int warn_extern_inline;
+/* Non-zero means warn when the compiler will reorder code. */
+int warn_reorder;
+
+/* Non-zero means warn when sysnthesis behavior differs from Cfront's. */
+int warn_synth;
+
/* Nonzero means `$' can be in an identifier.
See cccp.c for reasons why this breaks some obscure ANSI C programs. */
@@ -320,6 +331,9 @@ int flag_huge_objects;
definitions. */
int flag_conserve_space;
+/* Nonzero if we want to obey access control semantics. */
+int flag_access_control = 1;
+
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
@@ -361,6 +375,8 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1},
{"short-temps", &flag_short_temps, 1},
+ {"access-control", &flag_access_control, 1},
+ {"nonansi-builtins", &flag_no_nonansi_builtin, 0}
};
/* Decode the string P as a language-specific option.
@@ -447,6 +463,10 @@ lang_decode_option (p)
flag_alt_external_templates = 0;
found = 1;
}
+ else if (!strcmp (p, "ansi-overloading"))
+ {
+ warning ("-fansi-overloading is no longer meaningful");
+ }
else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
j++)
@@ -511,6 +531,10 @@ lang_decode_option (p)
warn_nonvdtor = setting;
else if (!strcmp (p, "extern-inline"))
warn_extern_inline = setting;
+ else if (!strcmp (p, "reorder"))
+ warn_reorder = setting;
+ else if (!strcmp (p, "synth"))
+ warn_synth = setting;
else if (!strcmp (p, "comment"))
; /* cpp handles this one. */
else if (!strcmp (p, "comments"))
@@ -537,6 +561,7 @@ lang_decode_option (p)
if (warn_uninitialized != 1)
warn_uninitialized = (setting ? 2 : 0);
warn_template_debugging = setting;
+ warn_reorder = setting;
}
else if (!strcmp (p, "overloaded-virtual"))
@@ -544,7 +569,8 @@ lang_decode_option (p)
else return 0;
}
else if (!strcmp (p, "-ansi"))
- flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1;
+ flag_no_asm = 1, dollars_in_ident = 0, flag_no_nonansi_builtin = 1,
+ flag_ansi = 1;
#ifdef SPEW_DEBUG
/* Undocumented, only ever used when you're invoking cc1plus by hand, since
it's probably safe to assume no sane person would ever want to use this
@@ -983,7 +1009,7 @@ grok_array_decl (array_expr, index_exp)
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_ARRAY_REF (type))
return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
- array_expr, index_exp, NULL_TREE);
+ array_expr, index_exp, NULL_TREE);
/* Otherwise, create an ARRAY_REF for a pointer or array type. */
if (TREE_CODE (type) == POINTER_TYPE
@@ -1000,17 +1026,14 @@ grok_array_decl (array_expr, index_exp)
|| TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
- if (TYPE_LANG_SPECIFIC (type)
- && TYPE_OVERLOADS_ARRAY_REF (type))
- error ("array expression backwards");
- else if (TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == ARRAY_TYPE)
+ if (TREE_CODE (type) == POINTER_TYPE
+ || TREE_CODE (type) == ARRAY_TYPE)
return build_array_ref (index_exp, array_expr);
- else
- error("`[]' applied to non-pointer type");
- /* We gave an error, so give an error. Huh? */
- return error_mark_node;
+ /* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */
+ return build_indirect_ref (build_binary_op (PLUS_EXPR, array_expr,
+ index_exp, 1),
+ "array indexing");
}
/* Given the cast expression EXP, checking out its validity. Either return
@@ -1057,11 +1080,20 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return build1 (NOP_EXPR, void_type_node, t);
}
- /* You can't delete a pointer to constant. */
- if (code == POINTER_TYPE && TREE_READONLY (TREE_TYPE (type)))
+ if (code == POINTER_TYPE)
{
- error ("`const *' cannot be deleted");
- return error_mark_node;
+ /* You can't delete a pointer to constant. */
+ if (TREE_READONLY (TREE_TYPE (type)))
+ {
+ error ("`const *' cannot be deleted");
+ return error_mark_node;
+ }
+ /* You also can't delete functions. */
+ if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
+ {
+ error ("cannot delete a function");
+ return error_mark_node;
+ }
}
#if 0
@@ -1128,13 +1160,13 @@ check_classfn (ctype, cname, function)
}
if (methods != end)
- cp_error ("argument list for `%D' does not match any in class `%T'",
- fn_name, ctype);
+ cp_error ("argument list for `%#D' does not match any in class `%T'",
+ function, ctype);
else
{
methods = 0;
- cp_error ("no `%D' member function declared in class `%T'",
- fn_name, ctype);
+ cp_error ("no `%#D' member function declared in class `%T'",
+ function, ctype);
}
/* If we did not find the method in the class, add it to
@@ -1301,19 +1333,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
/* current_class_type can be NULL_TREE in case of error. */
if (asmspec == 0 && current_class_type)
{
- tree name;
- char *buf, *buf2;
-
- buf2 = build_overload_name (current_class_type, 1, 1);
- buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (value))
- + sizeof (STATIC_NAME_FORMAT)
- + strlen (buf2));
- sprintf (buf, STATIC_NAME_FORMAT, buf2,
- IDENTIFIER_POINTER (DECL_NAME (value)));
- name = get_identifier (buf);
TREE_PUBLIC (value) = 1;
DECL_INITIAL (value) = error_mark_node;
- DECL_ASSEMBLER_NAME (value) = name;
+ DECL_ASSEMBLER_NAME (value)
+ = build_static_name (current_class_type, DECL_NAME (value));
}
pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics);
@@ -1366,9 +1389,11 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
if (DECL_FRIEND_P (value))
return void_type_node;
+#if 0 /* Just because a fn is declared doesn't mean we'll try to define it. */
if (current_function_decl && ! IS_SIGNATURE (current_class_type))
cp_error ("method `%#D' of local class must be defined in class body",
value);
+#endif
DECL_IN_AGGR_P (value) = 1;
return value;
@@ -2067,9 +2092,13 @@ finish_anon_union (anon_union_decl)
return;
}
- while (field)
+ for (; field; field = TREE_CHAIN (field))
{
- tree decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
+ tree decl;
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
/* tell `pushdecl' that this is not tentative. */
DECL_INITIAL (decl) = error_mark_node;
TREE_PUBLIC (decl) = public_p;
@@ -2096,12 +2125,19 @@ finish_anon_union (anon_union_decl)
TREE_PURPOSE of the following TREE_LIST. */
elems = tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type;
- field = TREE_CHAIN (field);
}
if (static_p)
{
- make_decl_rtl (main_decl, 0, global_bindings_p ());
- DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+ if (main_decl)
+ {
+ make_decl_rtl (main_decl, 0, global_bindings_p ());
+ DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+ }
+ else
+ {
+ warning ("anonymous union with no members");
+ return;
+ }
}
/* The following call assumes that there are never any cleanups
@@ -2522,6 +2558,37 @@ walk_sigtables (typedecl_fn, vardecl_fn)
}
}
+/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
+ inline function at end-of-file. */
+
+void
+import_export_inline (decl)
+ tree decl;
+{
+ if (TREE_PUBLIC (decl))
+ return;
+
+ /* If an explicit instantiation doesn't have TREE_PUBLIC set, it was with
+ 'extern'. */
+ if (DECL_EXPLICIT_INSTANTIATION (decl)
+ || (DECL_IMPLICIT_INSTANTIATION (decl) && ! flag_implicit_templates))
+ {
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ }
+ else if (DECL_FUNCTION_MEMBER_P (decl))
+ {
+ tree ctype = DECL_CLASS_CONTEXT (decl);
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+ {
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl)
+ = (CLASSTYPE_INTERFACE_ONLY (ctype)
+ || (DECL_INLINE (decl) && ! flag_implement_inlines));
+ }
+ }
+}
+
extern int parse_time, varconst_time;
#define TIMEVAR(VAR, BODY) \
@@ -2541,8 +2608,7 @@ finish_file ()
tree fnname;
tree vars = static_aggregates;
int needs_cleaning = 0, needs_messing_up = 0;
-
- build_exception_table ();
+ int have_exception_handlers = build_exception_table ();
if (flag_detailed_statistics)
dump_tree_statistics ();
@@ -2636,7 +2702,7 @@ finish_file ()
mess_up:
/* Must do this while we think we are at the top level. */
vars = nreverse (static_aggregates);
- if (vars != NULL_TREE)
+ if (vars != NULL_TREE || have_exception_handlers)
{
fnname = get_file_function_name ('I');
start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0);
@@ -2648,6 +2714,9 @@ finish_file ()
push_momentary ();
expand_start_bindings (0);
+ if (have_exception_handlers)
+ register_exception_table ();
+
while (vars)
{
tree decl = TREE_VALUE (vars);
@@ -2712,7 +2781,6 @@ finish_file ()
}
}
if (IS_AGGR_TYPE (TREE_TYPE (decl))
- || init == 0
|| TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
expand_aggr_init (decl, init, 0);
else if (TREE_CODE (init) == TREE_VEC)
@@ -2828,24 +2896,12 @@ finish_file ()
0; don't crash. */
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
continue;
- if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (decl))
- {
- tree ctype = DECL_CLASS_CONTEXT (decl);
- if (CLASSTYPE_INTERFACE_KNOWN (ctype))
- {
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl)
- = (CLASSTYPE_INTERFACE_ONLY (ctype)
- || (DECL_INLINE (decl) && ! flag_implement_inlines));
- }
- }
+ import_export_inline (decl);
if (TREE_PUBLIC (decl)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|| flag_keep_inline_functions)
{
- if (DECL_EXTERNAL (decl)
- || (DECL_IMPLICIT_INSTANTIATION (decl)
- && ! flag_implicit_templates))
+ if (DECL_EXTERNAL (decl))
assemble_external (decl);
else
{
@@ -2872,9 +2928,7 @@ finish_file ()
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& ! TREE_ASM_WRITTEN (decl))
{
- if (DECL_EXTERNAL (decl)
- || (DECL_IMPLICIT_INSTANTIATION (decl)
- && ! flag_implicit_templates))
+ if (DECL_EXTERNAL (decl))
assemble_external (decl);
else
{
OpenPOWER on IntegriCloud