#include "tm_p.h"
#include "target.h"
#include "c-common.h"
+#include "c-pragma.h"
#include "diagnostic.h"
extern const struct attribute_spec *lang_attribute_table;
static void set_identifier_type_value_with_scope
PARAMS ((tree, tree, struct binding_level *));
static void record_unknown_type PARAMS ((tree, const char *));
+static tree builtin_function_1 PARAMS ((const char *, tree, tree, int,
+ enum built_in_class, const char *));
static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
s->bindings = b;
s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl;
+ s->last_parms = last_function_parms;
scope_chain = s;
current_function_decl = NULL_TREE;
if (s->need_pop_function_context)
pop_function_context_from (NULL_TREE);
current_function_decl = s->function_decl;
+ last_function_parms = s->last_parms;
free (s);
}
{
if (TREE_CODE (newdecl) != FUNCTION_DECL)
{
+ /* Avoid warnings redeclaring anticipated built-ins. */
+ if (DECL_ANTICIPATED (olddecl))
+ return 0;
+
/* If you declare a built-in or predefined function name as static,
the old definition is overridden, but optionally warn this was a
bad choice of name. */
}
else if (!types_match)
{
- if ((DECL_EXTERN_C_P (newdecl)
+ /* Avoid warnings redeclaring anticipated built-ins. */
+ 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))))
&& namespace_bindings_p ())
? "`%#D' previously defined here"
: "`%#D' previously declared here", olddecl);
+ return 0;
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_INITIAL (olddecl) != NULL_TREE
if (1 == simple_cst_equal (TREE_PURPOSE (t1),
TREE_PURPOSE (t2)))
{
- if (pedantic)
- {
- pedwarn ("default argument given for parameter %d of `%#D'",
- i, newdecl);
- cp_pedwarn_at ("after previous specification in `%#D'",
- olddecl);
- }
+ pedwarn ("default argument given for parameter %d of `%#D'",
+ i, newdecl);
+ cp_pedwarn_at ("after previous specification in `%#D'",
+ olddecl);
}
else
{
except for any that we copy here from the old type. */
DECL_ATTRIBUTES (newdecl)
= (*targetm.merge_decl_attributes) (olddecl, newdecl);
+ decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0);
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
tree newtype;
/* Merge the data types specified in the two decls. */
- newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
+ newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
- /* If common_type produces a non-typedef type, just use the old type. */
+ /* If merge_types produces a non-typedef type, just use the old type. */
if (TREE_CODE (newdecl) == TYPE_DECL
&& newtype == DECL_ORIGINAL_TYPE (newdecl))
newtype = oldtype;
if (TREE_CODE (newdecl) == VAR_DECL)
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
- /* Do this after calling `common_type' so that default
+ /* Do this after calling `merge_types' so that default
parameters don't confuse us. */
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))
TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
+ COPY_DECL_RTL (newdecl, olddecl);
}
/* Merge the storage class information. */
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
sizeof (struct tree_decl) - sizeof (struct tree_common)
- + tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *));
+ + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
}
DECL_UID (olddecl) = olddecl_uid;
if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old)))
old = NULL_TREE;
if (old && TREE_CODE (old) != form
- && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL))
+ && (form == ENUMERAL_TYPE || TREE_CODE (old) == ENUMERAL_TYPE))
{
error ("`%#D' redeclared as %C", old, form);
return NULL_TREE;
if (TREE_PURPOSE (tail) == name)
{
enum tree_code code = TREE_CODE (TREE_VALUE (tail));
- /* Should tighten this up; it'll probably permit
- UNION_TYPE and a struct template, for example. */
+
if (code != form
- && !(form != ENUMERAL_TYPE && code == TEMPLATE_DECL))
+ && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
{
/* Definition isn't the kind we were looking for. */
- error ("`%#D' redeclared as %C", TREE_VALUE (tail),
- form);
+ error ("`%#D' redeclared as %C", TREE_VALUE (tail), form);
return NULL_TREE;
}
return TREE_VALUE (tail);
/*in_decl=*/NULL_TREE,
/*context=*/NULL_TREE,
/*entering_scope=*/0,
- /*complain=*/1);
+ tf_error | tf_warning);
else if (DECL_FUNCTION_TEMPLATE_P (val)
|| TREE_CODE (val) == OVERLOAD)
val = lookup_template_function (val,
/* If we have a single function from a using decl, pull it out. */
if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
val = OVL_FUNCTION (val);
- return val;
+
+ /* Ignore built-in functions that haven't been prototyped yet. */
+ if (!val || !DECL_P(val)
+ || !DECL_LANG_SPECIFIC(val)
+ || !DECL_ANTICIPATED (val))
+ return val;
}
error ("`%D' undeclared in namespace `%D'", name, namespace);
/* Resolve `typename CONTEXT::NAME'. Returns an appropriate type,
unless an error occurs, in which case error_mark_node is returned.
- If COMPLAIN zero, don't complain about any errors that occur. */
+ If we locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is
+ set, we return that, rather than the _TYPE it corresponds to, in
+ other cases we look through the type decl. If TF_ERROR is set,
+ complain about errors, otherwise be quiet. */
tree
make_typename_type (context, name, complain)
tree context, name;
- int complain;
+ tsubst_flags_t complain;
{
tree fullname;
{
/* We can get here from typename_sub0 in the explicit_template_type
expansion. Just fail. */
- if (complain)
+ if (complain & tf_error)
error ("no class template named `%#T' in `%#T'",
name, context);
return error_mark_node;
tmpl = lookup_field (context, name, 0, 0);
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
- if (complain)
+ if (complain & tf_error)
error ("no class template named `%#T' in `%#T'",
name, context);
return error_mark_node;
TREE_OPERAND (fullname, 1),
NULL_TREE, context,
/*entering_scope=*/0,
- /*complain=*/1);
+ tf_error | tf_warning);
}
else
{
if (!IS_AGGR_TYPE (context))
{
- if (complain)
+ if (complain & tf_error)
error ("no type named `%#T' in `%#T'", name, context);
return error_mark_node;
}
t = lookup_field (context, name, 0, 1);
if (t)
- return TREE_TYPE (t);
+ {
+ if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
+ t = TREE_TYPE (t);
+ return t;
+ }
}
}
there now or its never going to be. */
if (!uses_template_parms (context))
{
- if (complain)
+ if (complain & tf_error)
error ("no type named `%#T' in `%#T'", name, context);
return error_mark_node;
}
/* Resolve `CONTEXT::template NAME'. Returns an appropriate type,
unless an error occurs, in which case error_mark_node is returned.
- If COMPLAIN zero, don't complain about any errors that occur. */
+ If we locate a TYPE_DECL, we return that, rather than the _TYPE it
+ corresponds to. If COMPLAIN zero, don't complain about any errors
+ that occur. */
tree
make_unbound_class_template (context, name, complain)
tree val;
val = BINDING_VALUE (binding);
- /* When we implicitly declare some builtin entity, we mark it
- DECL_ANTICIPATED, so that we know to ignore it until it is
- really declared. */
- if (val && DECL_P (val)
- && DECL_LANG_SPECIFIC (val)
- && DECL_ANTICIPATED (val))
- return NULL_TREE;
-
if (LOOKUP_NAMESPACES_ONLY (flags))
{
/* We are not interested in types. */
*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
val = binding_for_name (name, scope);
- /* Initialize binding for this context. */
- BINDING_VALUE (b) = BINDING_VALUE (val);
- BINDING_TYPE (b) = BINDING_TYPE (val);
+ /* Ignore anticipated built-in functions. */
+ if (val && BINDING_VALUE (val)
+ && DECL_P (BINDING_VALUE (val))
+ && DECL_LANG_SPECIFIC (BINDING_VALUE (val))
+ && DECL_ANTICIPATED (BINDING_VALUE (val)))
+ {
+ BINDING_VALUE (b) = NULL_TREE;
+ BINDING_TYPE (b) = NULL_TREE;
+ }
+ else
+ {
+ /* Initialize binding for this context. */
+ BINDING_VALUE (b) = BINDING_VALUE (val);
+ BINDING_TYPE (b) = BINDING_TYPE (val);
+ }
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
flag_inline_functions = 0;
}
- /* In C++, we never create builtin functions whose name does not
- begin with `__'. Users should be using headers to get prototypes
- in C++. It would be nice if we could warn when `-fbuiltin' is
- used explicitly, but we do not have that information. */
- flag_no_builtin = 1;
-
/* Initially, C. */
current_lang_name = lang_name_c;
/* Perform other language dependent initializations. */
init_class_processing ();
- init_init_processing ();
init_search_processing ();
init_rtti_processing ();
flag_const_strings = 0;
/* Add GC roots for all of our global variables. */
- ggc_add_tree_root (c_global_trees, sizeof c_global_trees / sizeof(tree));
- ggc_add_tree_root (cp_global_trees, sizeof cp_global_trees / sizeof(tree));
+ ggc_add_tree_root (c_global_trees, ARRAY_SIZE (c_global_trees));
+ ggc_add_tree_root (cp_global_trees, ARRAY_SIZE (cp_global_trees));
ggc_add_tree_root (&integer_three_node, 1);
ggc_add_tree_root (&integer_two_node, 1);
ggc_add_tree_root (&signed_size_zero_node, 1);
return decl;
}
-/* Entry point for the benefit of c_common_nodes_and_builtins.
-
- Make a definition for a builtin function named NAME and whose data type
- is TYPE. TYPE should be a function type with argument types.
+/* Make a definition for a builtin function named NAME in the current
+ namespace, whose data type is TYPE and whose context is CONTEXT.
+ TYPE should be a function type with argument types.
CLASS and CODE tell later passes how to compile calls to this function.
See tree.h for possible values.
If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. */
-tree
-builtin_function (name, type, code, class, libname)
+static tree
+builtin_function_1 (name, type, context, code, class, libname)
const char *name;
tree type;
+ tree context;
int code;
enum built_in_class class;
const char *libname;
tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = code;
+ DECL_CONTEXT (decl) = context;
- my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
+ /* The return builtins leave the current function. */
+ if (code == BUILT_IN_RETURN || code == BUILT_IN_EH_RETURN)
+ TREE_THIS_VOLATILE (decl) = 1;
- /* All builtins that don't begin with an `_' should go in the `std'
- namespace. */
- if (name[0] != '_')
- {
- push_namespace (std_identifier);
- DECL_CONTEXT (decl) = std_node;
- }
pushdecl (decl);
- if (name[0] != '_')
- pop_namespace ();
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
we cannot change DECL_ASSEMBLER_NAME until we have installed this
return decl;
}
+/* Entry point for the benefit of c_common_nodes_and_builtins.
+
+ Make a defintion for a builtin function named NAME and whose data type
+ is TYPE. TYPE should be a function type with argument types. This
+ function places the anticipated declaration in the global namespace
+ and additionally in the std namespace if appropriate.
+
+ CLASS and CODE tell later passes how to compile calls to this function.
+ See tree.h for possible values.
+
+ If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
+ the name to be called if we can't opencode the function. */
+
+tree
+builtin_function (name, type, code, class, libname)
+ const char *name;
+ tree type;
+ int code;
+ enum built_in_class class;
+ const char *libname;
+{
+ /* All builtins that don't begin with an '_' should additionally
+ go in the 'std' namespace. */
+ if (name[0] != '_')
+ {
+ push_namespace (std_identifier);
+ builtin_function_1 (name, type, std_node, code, class, libname);
+ pop_namespace ();
+ }
+
+ return builtin_function_1 (name, type, NULL_TREE, code, class, libname);
+}
+
/* Generate a FUNCTION_DECL with the typical flags for a runtime library
function. Not called directly. */
attributes. */
void
-insert_default_attributes (decl)
+cxx_insert_default_attributes (decl)
tree decl;
{
if (!DECL_EXTERN_C_FUNCTION_P (decl))
/* Set attributes here so if duplicate decl, will have proper attributes. */
cplus_decl_attributes (&decl, attributes, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl);
+
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
DECL_STMT is expanded. */
defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
- /* We try to defer namespace-scope static constants so that they are
- not emitted into the object file unnecessarily. */
- if (!DECL_VIRTUAL_P (decl)
- && TREE_READONLY (decl)
- && DECL_INITIAL (decl) != NULL_TREE
- && DECL_INITIAL (decl) != error_mark_node
- && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
- && toplev
- && !TREE_PUBLIC (decl))
- {
- /* Fool with the linkage according to #pragma interface. */
- if (!interface_unknown)
+ /* We try to defer namespace-scope static constants and template
+ instantiations so that they are not emitted into the object file
+ unnecessarily. */
+ if ((!DECL_VIRTUAL_P (decl)
+ && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != NULL_TREE
+ && DECL_INITIAL (decl) != error_mark_node
+ && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
+ && toplev
+ && !TREE_PUBLIC (decl))
+ || DECL_COMDAT (decl))
+ {
+ /* Fool with the linkage of static consts according to #pragma
+ interface. */
+ if (!interface_unknown && !TREE_PUBLIC (decl))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = interface_only;
return;
/* Compute the cleanup. */
- cleanup = maybe_build_cleanup (decl);
+ cleanup = cxx_maybe_build_cleanup (decl);
/* Record the cleanup required for this declaration. */
- if (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node
- && cleanup)
+ if (DECL_SIZE (decl) && cleanup)
finish_decl_cleanup (decl, cleanup);
}
}
/* If a name was specified, get the string. */
+ if (current_binding_level == global_binding_level)
+ asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree)
- asmspec = TREE_STRING_POINTER (asmspec_tree);
+ asmspec = TREE_STRING_POINTER (asmspec_tree);
if (init && TREE_CODE (init) == NAMESPACE_DECL)
{
tree spec;
tree type = NULL_TREE;
int longlong = 0;
- int constp;
- int restrictp;
- int volatilep;
int type_quals;
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
}
}
}
- /* C++ aggregate types. */
else if (TREE_CODE (id) == TYPE_DECL)
{
if (type)
{
type = TREE_TYPE (id);
TREE_VALUE (spec) = type;
+ typedef_decl = id;
}
goto found;
}
else
{
type = TREE_TYPE (t);
-#if 0
- /* See the code below that used this. */
- decl_attr = DECL_ATTRIBUTES (id);
-#endif
typedef_decl = t;
}
}
found: ;
}
+#if 0
+ /* See the code below that used this. */
+ if (typedef_decl)
+ decl_attr = DECL_ATTRIBUTES (typedef_decl);
+#endif
typedef_type = type;
/* No type at all: default to `int', and set DEFAULTED_INT
type = integer_type_node;
}
- if (type && TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type))
+ if (type && IMPLICIT_TYPENAME_P (type))
{
/* The implicit typename extension is deprecated and will be
removed. Warn about its use now. */
type = build_complex_type (type);
}
- if (sfk == sfk_conversion
- && (RIDBIT_SETP (RID_CONST, specbits)
- || RIDBIT_SETP (RID_VOLATILE, specbits)
- || RIDBIT_SETP (RID_RESTRICT, specbits)))
+ type_quals = TYPE_UNQUALIFIED;
+ if (RIDBIT_SETP (RID_CONST, specbits))
+ type_quals |= TYPE_QUAL_CONST;
+ if (RIDBIT_SETP (RID_VOLATILE, specbits))
+ type_quals |= TYPE_QUAL_VOLATILE;
+ if (RIDBIT_SETP (RID_RESTRICT, specbits))
+ type_quals |= TYPE_QUAL_RESTRICT;
+ if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)
error ("qualifiers are not allowed on declaration of `operator %T'",
ctor_return_type);
- /* Set CONSTP if this declaration is `const', whether by
- explicit specification or via a typedef.
- Likewise for VOLATILEP. */
-
- constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type);
- restrictp =
- !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type);
- volatilep =
- !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type);
- type_quals = ((constp ? TYPE_QUAL_CONST : 0)
- | (restrictp ? TYPE_QUAL_RESTRICT : 0)
- | (volatilep ? TYPE_QUAL_VOLATILE : 0));
- type = cp_build_qualified_type (type, type_quals);
+ type_quals |= cp_type_quals (type);
+ type = cp_build_qualified_type_real
+ (type, type_quals, ((typedef_decl && !DECL_ARTIFICIAL (typedef_decl)
+ ? tf_ignore_bad_quals : 0) | tf_error | tf_warning));
+ /* We might have ignored or rejected some of the qualifiers. */
+ type_quals = cp_type_quals (type);
+
staticp = 0;
inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
{
register tree typemodlist;
int erred = 0;
-
- constp = 0;
- volatilep = 0;
- restrictp = 0;
+ int constp = 0;
+ int volatilep = 0;
+ int restrictp = 0;
+
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
tree qualifier = TREE_VALUE (typemodlist);
if (qualifier == ridpointers[(int) RID_CONST])
- constp++;
+ {
+ constp++;
+ type_quals |= TYPE_QUAL_CONST;
+ }
else if (qualifier == ridpointers[(int) RID_VOLATILE])
- volatilep++;
+ {
+ volatilep++;
+ type_quals |= TYPE_QUAL_VOLATILE;
+ }
else if (qualifier == ridpointers[(int) RID_RESTRICT])
- restrictp++;
+ {
+ restrictp++;
+ type_quals |= TYPE_QUAL_RESTRICT;
+ }
else if (!erred)
{
erred = 1;
pedwarn ("duplicate `volatile'");
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
-
- type_quals = ((constp ? TYPE_QUAL_CONST : 0)
- | (restrictp ? TYPE_QUAL_RESTRICT : 0)
- | (volatilep ? TYPE_QUAL_VOLATILE : 0));
- if (TREE_CODE (declarator) == ADDR_EXPR
- && (constp || volatilep))
- {
- if (constp)
- pedwarn ("discarding `const' applied to a reference");
- if (volatilep)
- pedwarn ("discarding `volatile' applied to a reference");
- type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- }
type = cp_build_qualified_type (type, type_quals);
+ type_quals = cp_type_quals (type);
}
declarator = TREE_OPERAND (declarator, 0);
ctype = NULL_TREE;
&& uses_template_parms (current_class_type))
{
tree args = current_template_args ();
- type = tsubst (type, args, /*complain=*/1, NULL_TREE);
+ type = tsubst (type, args, tf_error | tf_warning,
+ NULL_TREE);
}
/* This pop_nested_class corresponds to the
else if (type_quals & TYPE_QUAL_CONST)
{
error ("const `%s' cannot be declared `mutable'", name);
- RIDBIT_RESET (RID_MUTABLE, specbits);
+ RIDBIT_RESET (RID_MUTABLE, specbits);
}
}
/* Detect the case of an array type of unspecified size
which came, as such, direct from a typedef name.
- We must copy the type, so that each identifier gets
- a distinct type, so that each identifier's size can be
- controlled separately by its own initializer. */
+ We must copy the type, so that the array's domain can be
+ individually set by the object's initializer. */
- if (type != 0 && typedef_type != 0
- && TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == 0
+ if (type && typedef_type
+ && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
&& TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
- {
- type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type));
- }
+ type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
/* Detect where we're using a typedef of function type to declare a
function. last_function_parms will not be set, so we must create
/* Only try to do this stuff if we didn't already give up. */
if (type != integer_type_node)
{
- /* DR 209. The friendly class does not need to be accessible
- in the scope of the class granting friendship. */
- skip_type_access_control ();
+ decl_type_access_control (TYPE_NAME (type));
/* A friendly class? */
if (current_class_type)
if (friendp)
{
/* Friends are treated specially. */
- tree t = NULL_TREE;
-
- /* DR 209. The friend does not need to be accessible at this
- point. */
- skip_type_access_control ();
-
if (ctype == current_class_type)
warning ("member functions are implicitly friends of their class");
-
- if (decl && DECL_NAME (decl))
- {
- if (template_class_depth (current_class_type) == 0)
- {
- decl = check_explicit_specialization
- (declarator, decl,
- template_count, 2 * (funcdef_flag != 0) + 4);
- if (decl == error_mark_node)
- return error_mark_node;
- }
-
- t = do_friend (ctype, declarator, decl,
- last_function_parms, *attrlist, flags, quals,
- funcdef_flag);
- }
- if (t && funcdef_flag)
- return t;
- return void_type_node;
+ else
+ {
+ tree t = NULL_TREE;
+ if (decl && DECL_NAME (decl))
+ {
+ if (template_class_depth (current_class_type) == 0)
+ {
+ decl
+ = check_explicit_specialization
+ (declarator, decl,
+ template_count, 2 * (funcdef_flag != 0) + 4);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ }
+
+ t = do_friend (ctype, declarator, decl,
+ last_function_parms, *attrlist,
+ flags, quals, funcdef_flag);
+ }
+ if (t && funcdef_flag)
+ return t;
+
+ return void_type_node;
+ }
}
/* Structure field. It may not be a function, except for C++ */
redeclare_class_template (ref, current_template_parms);
}
- /* Until the type is defined, tentatively accept whatever
- structure tag the user hands us. */
- if (!COMPLETE_TYPE_P (ref)
- && ref != current_class_type
- /* Have to check this, in case we have contradictory tag info. */
- && IS_AGGR_TYPE_CODE (TREE_CODE (ref)))
- {
- if (tag_code == class_type)
- CLASSTYPE_DECLARED_CLASS (ref) = 1;
- else if (tag_code == record_type)
- CLASSTYPE_DECLARED_CLASS (ref) = 0;
- }
-
TYPE_ATTRIBUTES (ref) = attributes;
return ref;
pushtag (name, enumtype, 0);
}
- if (current_class_type)
- TREE_ADDRESSABLE (b->tags) = 1;
-
return enumtype;
}
cplus_decl_attributes (&decl1, attrs, 0);
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_binding_level == global_binding_level)
+ maybe_apply_pragma_weak (decl1);
+
fntype = TREE_TYPE (decl1);
restype = TREE_TYPE (fntype);
DECL_UNINLINABLE (fndecl) = 1;
/* Complain if there's just no return statement. */
- if (!processing_template_decl
+ if (warn_return_type
+ && !processing_template_decl
&& TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
- && !current_function_returns_value
- && !DECL_NAME (DECL_RESULT (fndecl))
+ && !current_function_returns_value && !current_function_returns_null
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
- /* If we have -Wreturn-type, let flow complain. Unless we're an
+ && !DECL_NAME (DECL_RESULT (fndecl))
+ /* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
- && (!warn_return_type || DECL_INLINE (fndecl)))
+ && DECL_INLINE (fndecl))
warning ("no return statement in function returning non-void");
/* Clear out memory we no longer need. */
{
tree cleanup;
expand_decl (decl);
- cleanup = maybe_build_cleanup (decl);
+ cleanup = cxx_maybe_build_cleanup (decl);
expand_decl_init (decl);
if (! expand_decl_cleanup (decl, cleanup))
error ("parser lost in parsing declaration of `%D'",
here. */
tree
-maybe_build_cleanup (decl)
+cxx_maybe_build_cleanup (decl)
tree decl;
{
tree type = TREE_TYPE (decl);
return rval;
}
- return 0;
+ return NULL_TREE;
}
\f
/* When a stmt has been parsed, this function is called. */
}
void
-lang_mark_tree (t)
+cxx_mark_tree (t)
tree t;
{
enum tree_code code = TREE_CODE (t);