#include "ggc.h"
#include "expr.h"
#include "c-common.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
#include "tm_p.h"
#include "obstack.h"
+#include "c-lex.h"
#include "cpplib.h"
#include "target.h"
cpp_reader *parse_in; /* Declared in c-lex.h. */
: "long long unsigned int"))
#endif
+/* The variant of the C language being processed. */
+
+enum c_language_kind c_language;
+
/* The following symbols are subsumed in the c_global_trees array, and
listed here individually for documentation purposes.
tree void_list_node;
- The lazily created VAR_DECLS for __FUNCTION__, __PRETTY_FUNCTION__,
+ The lazily created VAR_DECLs for __FUNCTION__, __PRETTY_FUNCTION__,
and __func__. (C doesn't generate __FUNCTION__ and__PRETTY_FUNCTION__
VAR_DECLS, but C++ does.)
tree function_name_decl_node;
- tree pretty_function_name_declnode;
+ tree pretty_function_name_decl_node;
tree c99_function_name_decl_node;
Stack of nested function name VAR_DECLs.
if (body)
{
- /* They were called into existance, so add to statement tree. */
+ /* They were called into existence, so add to statement tree. */
body = chainon (body,
TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
body = build_stmt (COMPOUND_STMT, body);
now. RID indicates how it should be formatted and IDENTIFIER_NODE
ID is its name (unfortunately C and C++ hold the RID values of
keywords in different places, so we can't derive RID from ID in
- this language independant code. */
+ this language independent code. */
tree
fname_decl (rid, id)
wide_flag = 1;
}
else
- length += (TREE_STRING_LENGTH (t) - 1);
+ {
+ length += (TREE_STRING_LENGTH (t) - 1);
+ if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
+ warning ("concatenation of string literals with __FUNCTION__ is deprecated. This feature will be removed in future");
+ }
}
/* If anything is wide, the non-wides will be converted,
}
}
-/* Return nonzero if X is a tree that can be verified by the sequence poitn
+/* Return nonzero if X is a tree that can be verified by the sequence point
warnings. */
static int
warning_candidate_p (x)
{
/* Do default conversion if safe and possibly important,
in case within ({...}). */
- if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE && lvalue_p (expr))
+ if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
+ && (flag_isoc99 || lvalue_p (expr)))
|| TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
expr = default_conversion (expr);
return unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node;
- if (mode == TYPE_MODE (intQI_type_node))
+ if (mode == QImode)
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
- if (mode == TYPE_MODE (intHI_type_node))
+ if (mode == HImode)
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (mode == TYPE_MODE (intSI_type_node))
+ if (mode == SImode)
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (mode == TYPE_MODE (intDI_type_node))
+ if (mode == DImode)
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
return build_pointer_type (integer_type_node);
#ifdef VECTOR_MODE_SUPPORTED_P
- if (mode == TYPE_MODE (V4SF_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V4SF_type_node;
- if (mode == TYPE_MODE (V4SI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V4SI_type_node;
- if (mode == TYPE_MODE (V2SI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V2SI_type_node;
- if (mode == TYPE_MODE (V4HI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V4HI_type_node;
- if (mode == TYPE_MODE (V8QI_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V8QI_type_node;
- if (mode == TYPE_MODE (V2SF_type_node) && VECTOR_MODE_SUPPORTED_P (mode))
- return V2SF_type_node;
+ if (VECTOR_MODE_SUPPORTED_P (mode))
+ {
+ switch (mode)
+ {
+ case V16QImode:
+ return unsignedp ? unsigned_V16QI_type_node : V16QI_type_node;
+ case V8HImode:
+ return unsignedp ? unsigned_V8HI_type_node : V8HI_type_node;
+ case V4SImode:
+ return unsignedp ? unsigned_V4SI_type_node : V4SI_type_node;
+ case V2SImode:
+ return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
+ case V4HImode:
+ return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
+ case V8QImode:
+ return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
+ case V4SFmode:
+ return V4SF_type_node;
+ case V2SFmode:
+ return V2SF_type_node;
+ default:
+ break;
+ }
+ }
#endif
return 0;
Technically, this approach is actually more conservative that
it needs to be. In particular, `const int *' and `int *'
- chould be in different alias sets, according to the C and C++
+ should be in different alias sets, according to the C and C++
standard, since their types are not the same, and so,
technically, an `int **' and `const int **' cannot point at
the same thing.
tree va_list_arg_type_node;
/* We must initialize this before any builtin functions (which might have
- attributes) are declared. (c_common_lang_init is too late.) */
+ attributes) are declared. (c_common_init is too late.) */
format_attribute_table = c_format_attribute_table;
/* Define `int' and `char' first so that dbx will output them first. */
}
+/* Linked list of disabled built-in functions. */
+
+typedef struct disabled_builtin
+{
+ const char *name;
+ struct disabled_builtin *next;
+} disabled_builtin;
+static disabled_builtin *disabled_builtins = NULL;
+
+static bool builtin_function_disabled_p PARAMS ((const char *));
+
+/* Disable a built-in function specified by -fno-builtin-NAME. If NAME
+ begins with "__builtin_", give an error. */
+
+void
+disable_builtin_function (name)
+ const char *name;
+{
+ if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+ error ("cannot disable built-in function `%s'", name);
+ else
+ {
+ disabled_builtin *new = xmalloc (sizeof (disabled_builtin));
+ new->name = name;
+ new->next = disabled_builtins;
+ disabled_builtins = new;
+ }
+}
+
+
+/* Return true if the built-in function NAME has been disabled, false
+ otherwise. */
+
+static bool
+builtin_function_disabled_p (name)
+ const char *name;
+{
+ disabled_builtin *p;
+ for (p = disabled_builtins; p != NULL; p = p->next)
+ {
+ if (strcmp (name, p->name) == 0)
+ return true;
+ }
+ return false;
+}
+
+
/* Possibly define a builtin function with one or two names. BUILTIN_NAME
is an __builtin_-prefixed name; NAME is the ordinary name; one or both
of these may be NULL (though both being NULL is useless).
TREE_SIDE_EFFECTS (bdecl) = 1;
}
}
- if (name != 0 && !flag_no_builtin && !(nonansi_p && flag_no_nonansi_builtin))
+ if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name)
+ && !(nonansi_p && flag_no_nonansi_builtin))
{
decl = builtin_function (name, type, function_code, class, NULL);
if (nonansi_p)
}
break;
+ case COMPOUND_LITERAL_EXPR:
+ {
+ /* Initialize the anonymous variable declared in the compound
+ literal, then return the variable. */
+ tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
+ emit_local_var (decl);
+ return expand_expr (decl, target, tmode, modifier);
+ }
+
default:
abort ();
}
return -1;
}
+/* Hook used by staticp to handle language-specific tree codes. */
+
+int
+c_staticp (exp)
+ tree exp;
+{
+ if (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
+ && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp)))
+ return 1;
+ return 0;
+}
+
/* Tree code classes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
static void c_init_attributes PARAMS ((void));
-/* Do the parts of lang_init common to C and C++. */
+/* Common initialization before parsing options. */
+void
+c_common_init_options (lang)
+ enum c_language_kind lang;
+{
+ c_language = lang;
+ parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89:
+ lang == clk_cplusplus ? CLK_GNUCXX: CLK_OBJC);
+
+ /* Mark as "unspecified" (see c_common_post_options). */
+ flag_bounds_check = -1;
+}
+
+/* Post-switch processing. */
void
-c_common_lang_init ()
+c_common_post_options ()
{
+ cpp_post_options (parse_in);
+
+ /* Use tree inlining if possible. Function instrumentation is only
+ done in the RTL level, so we disable tree inlining. */
+ if (! flag_instrument_function_entry_exit)
+ {
+ if (!flag_no_inline)
+ {
+ flag_inline_trees = 1;
+ flag_no_inline = 1;
+ }
+ if (flag_inline_functions)
+ {
+ flag_inline_trees = 2;
+ flag_inline_functions = 0;
+ }
+ }
+
/* If still "unspecified", make it match -fbounded-pointers. */
- if (flag_bounds_check < 0)
+ if (flag_bounds_check == -1)
flag_bounds_check = flag_bounded_pointers;
/* Special format checking options don't work without -Wformat; warn if
warning ("-Wformat-security ignored without -Wformat");
if (warn_missing_format_attribute && !warn_format)
warning ("-Wmissing-format-attribute ignored without -Wformat");
+}
+
+/* Front end initialization common to C, ObjC and C++. */
+const char *
+c_common_init (filename)
+ const char *filename;
+{
+ /* Do this before initializing pragmas, as then cpplib's hash table
+ has been set up. */
+ filename = init_c_lex (filename);
+
+ init_pragma ();
if (!c_attrs_initialized)
c_init_attributes ();
+
+ return filename;
+}
+
+/* Common finish hook for the C, ObjC and C++ front ends. */
+void
+c_common_finish ()
+{
+ cpp_finish (parse_in);
+
+ /* For performance, avoid tearing down cpplib's internal structures.
+ Call cpp_errors () instead of cpp_destroy (). */
+ errorcount += cpp_errors (parse_in);
}
static void
#undef DEF_ATTR_TREE_LIST
#undef DEF_FN_ATTR
}
+
+/* Output a -Wshadow warning MSGID about NAME, an IDENTIFIER_NODE, and
+ additionally give the location of the previous declaration DECL. */
+void
+shadow_warning (msgid, name, decl)
+ const char *msgid;
+ tree name, decl;
+{
+ warning ("declaration of `%s' shadows %s", IDENTIFIER_POINTER (name), msgid);
+ warning_with_file_and_line (DECL_SOURCE_FILE (decl),
+ DECL_SOURCE_LINE (decl),
+ "shadowed declaration is here");
+}
+