else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_CONTEXT (x) == NULL_TREE)
return push_overloaded_decl (x, 0);
- /* If declaring a type as a typedef, and the type has no known
- typedef name, install this TYPE_DECL as its typedef name. */
+ /* If declaring a type as a typedef, copy the type (unless we're
+ at line 0), and install this TYPE_DECL as the new type's typedef
+ name. See the extensive comment in ../c-decl.c (pushdecl). */
if (TREE_CODE (x) == TYPE_DECL)
{
tree type = TREE_TYPE (x);
- tree name = (type != error_mark_node) ? TYPE_NAME (type) : x;
-
- if (name == NULL_TREE || TREE_CODE (name) != TYPE_DECL)
- {
- /* If these are different names, and we're at the global
- binding level, make two equivalent definitions. */
- name = x;
- if (global_bindings_p ())
- TYPE_NAME (type) = x;
- }
- my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 140);
+ if (DECL_SOURCE_LINE (x) == 0)
+ {
+ if (TYPE_NAME (type) == 0)
+ TYPE_NAME (type) = x;
+ }
+ else if (type != error_mark_node && TYPE_NAME (type) != x)
+ {
+ DECL_ORIGINAL_TYPE (x) = type;
+ type = build_type_copy (type);
+ TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
+ TYPE_NAME (type) = x;
+ TREE_TYPE (x) = type;
+ }
if (type != error_mark_node
&& TYPE_NAME (type)
type = complete_type (type);
- if (type == void_type_node)
+ if (TREE_CODE (type) == VOID_TYPE)
val = IDENTIFIER_GLOBAL_VALUE (name);
else if (TREE_CODE (type) == NAMESPACE_DECL)
{
/* Have to make these distinct before we try using them. */
lang_name_cplusplus = get_identifier ("C++");
lang_name_c = get_identifier ("C");
+ lang_name_java = get_identifier ("Java");
/* enter the global namespace */
my_friendly_assert (global_namespace == NULL_TREE, 375);
int debug_temp_inits = 1;
tree
-start_decl (declarator, declspecs, initialized)
+start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
tree declarator, declspecs;
int initialized;
+ tree attributes, prefix_attributes;
{
register tree decl;
register tree type, tem;
decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
NULL_TREE);
- if (decl == NULL_TREE || decl == void_type_node)
+ if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
return NULL_TREE;
type = TREE_TYPE (decl);
pushclass (context, 2);
}
+ /* Set attributes here so if duplicate decl, will have proper attributes. */
+ cplus_decl_attributes (decl, attributes, prefix_attributes);
+
/* Add this decl to the current binding level, but not if it
comes from another scope, e.g. a static member variable.
TEM may equal DECL or it may be a previous decl of the same name. */
*next = TREE_OPERAND (decl, 0);
init = TREE_OPERAND (decl, 1);
- decl = start_decl (declarator, declspecs, 1);
+ decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE);
/* Look for __unused__ attribute */
if (TREE_USED (TREE_TYPE (decl)))
TREE_USED (decl) = 1;
constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type);
volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type);
- type = TYPE_MAIN_VARIANT (type);
+ type = build_type_variant (type, 0, 0);
staticp = 0;
inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
/* Check for some types that there cannot be arrays of. */
- if (TYPE_MAIN_VARIANT (type) == void_type_node)
+ if (TREE_CODE (type) == VOID_TYPE)
{
cp_error ("declaration of `%D' as array of voids", dname);
type = error_mark_node;
}
else
{
- if (TYPE_MAIN_VARIANT (type) == void_type_node)
+ if (TREE_CODE (type) == VOID_TYPE)
error ("invalid type: `void &'");
else
type = build_reference_type (type);
if (IS_SIGNATURE (current_class_type) && opaque_typedef)
SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1;
}
+ else if (current_lang_name == lang_name_java)
+ decl = build_lang_decl (TYPE_DECL, declarator, type);
else
decl = build_decl (TYPE_DECL, declarator, type);
We don't complain about parms either, but that is because
a better error message can be made later. */
- if (TYPE_MAIN_VARIANT (type) == void_type_node && decl_context != PARM)
+ if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM)
{
if (! declarator)
error ("unnamed variable or field declared void");
type = build_pointer_type (type);
else if (TREE_CODE (type) == OFFSET_TYPE)
type = build_pointer_type (type);
- else if (type == void_type_node && declarator)
+ else if (TREE_CODE (type) == VOID_TYPE && declarator)
{
error ("declaration of `%s' as void", name);
return NULL_TREE;
}
else if (first_parm != NULL_TREE
&& TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST
- && TREE_VALUE (first_parm) != void_type_node)
+ && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE)
my_friendly_abort (145);
else
{
chain = TREE_CHAIN (parm);
/* @@ weak defense against parse errors. */
- if (decl != void_type_node && TREE_CODE (decl) != TREE_LIST)
+ if (TREE_CODE (decl) != VOID_TYPE
+ && TREE_CODE (decl) != TREE_LIST)
{
/* Give various messages as the need arises. */
if (TREE_CODE (decl) == STRING_CST)
continue;
}
- if (decl != void_type_node)
+ if (TREE_CODE (decl) != VOID_TYPE)
{
decl = grokdeclarator (TREE_VALUE (decl),
TREE_PURPOSE (decl),
if (! decl)
continue;
type = TREE_TYPE (decl);
- if (TYPE_MAIN_VARIANT (type) == void_type_node)
+ if (TREE_CODE (type) == VOID_TYPE)
decl = void_type_node;
else if (TREE_CODE (type) == METHOD_TYPE)
{
}
}
- if (decl == void_type_node)
+ if (TREE_CODE (decl) == VOID_TYPE)
{
if (result == NULL_TREE)
{
cp_error ("`%D' must be either a non-static member function or a non-member function", decl);
if (p)
- for (; TREE_VALUE (p) != void_type_node ; p = TREE_CHAIN (p))
+ for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
{
tree arg = TREE_VALUE (p);
if (TREE_CODE (arg) == REFERENCE_TYPE)
int doing_friend = 0;
/* Sanity check. */
- my_friendly_assert (TREE_VALUE (void_list_node) == void_type_node, 160);
+ my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161);
/* Assume, until we see it does. */
/* Effective C++ rule 15. See also c_expand_return. */
if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
- && TREE_TYPE (fntype) == void_type_node)
+ && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE)
cp_warning ("`operator=' should return a reference to `*this'");
/* Make the init_value nonzero so pushdecl knows this is not tentative.
{
pushdecl (parm);
}
- else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
+ else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE)
cp_error ("parameter `%D' declared void", parm);
else
{
}
c_expand_return (current_class_ptr);
}
- else if (TYPE_MAIN_VARIANT (TREE_TYPE (
- DECL_RESULT (current_function_decl))) != void_type_node
+ else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE
&& return_label != NULL_RTX)
no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
cp_warning ("`noreturn' function `%D' does return", fndecl);
else if ((warn_return_type || pedantic)
&& current_function_returns_null
- && TYPE_MAIN_VARIANT (TREE_TYPE (fntype)) != void_type_node)
+ && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE)
{
/* If this function returns non-void and control can drop through,
complain. */
return NULL_TREE;
/* Pass friends other than inline friend functions back. */
- if (TYPE_MAIN_VARIANT (fndecl) == void_type_node)
+ if (fndecl == void_type_node)
return fndecl;
if (TREE_CODE (fndecl) != FUNCTION_DECL)
register tree link;
- if (TYPE_MAIN_VARIANT (decl) == void_type_node)
+ if (decl == void_type_node)
return decl;
old_initial = DECL_INITIAL (fndecl);
/* Every argument gets counted. */
typevec[maxtype++] = parmtype;
- if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
+ if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]
+ && ! is_java_type (parmtype))
{
Nrepeats++;
continue;
}
/* Only cache types which take more than one character. */
- if (parmtype != TYPE_MAIN_VARIANT (parmtype)
- || (TREE_CODE (parmtype) != INTEGER_TYPE
- && TREE_CODE (parmtype) != REAL_TYPE))
+ if ((parmtype != TYPE_MAIN_VARIANT (parmtype)
+ || (TREE_CODE (parmtype) != INTEGER_TYPE
+ && TREE_CODE (parmtype) != REAL_TYPE))
+ && ! is_java_type (parmtype))
TREE_USED (parmtype) = 1;
}
if (TYPE_PTRMEMFUNC_P (parmtype))
if (TREE_READONLY (parmtype))
OB_PUTC ('C');
- if (TREE_CODE (parmtype) == INTEGER_TYPE &&
- TYPE_MAIN_VARIANT (parmtype) ==
- unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
- OB_PUTC ('U');
+ if (TREE_CODE (parmtype) == INTEGER_TYPE
+ && (TYPE_MAIN_VARIANT (parmtype)
+ == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
+ && ! is_java_type (parmtype))
+ {
+ OB_PUTC ('U');
+ }
if (TYPE_VOLATILE (parmtype))
OB_PUTC ('V');
}
+/* True iff TYPE was declared as a "Java" type (inside extern "Java"). */
+
+int
+is_java_type (type)
+ tree type;
+{
+ if (TYPE_NAME (type) != NULL_TREE)
+ {
+ tree decl = TYPE_NAME (type);
+ if (TREE_CODE (decl) == TYPE_DECL
+ && DECL_LANG_SPECIFIC (decl) != NULL
+ && DECL_LANGUAGE (decl) == lang_java)
+ return 1;
+ }
+ return 0;
+}
+
/* Check to see if a tree node has been entered into the Bcode typelist
if not, add it. Otherwise emit the code and return TRUE */
static int
}
case INTEGER_TYPE:
+ /* "Java" integer types should mangle the same on all platforms,
+ and only depend on precision, not target 'int' size. */
+ if (is_java_type (parmtype))
+ {
+ if (TREE_UNSIGNED (parmtype))
+ {
+ switch (TYPE_PRECISION (parmtype))
+ {
+ case 8: OB_PUTC ('b'); return;
+ case 16: OB_PUTC ('w'); return;
+ }
+ }
+ else
+ {
+ switch (TYPE_PRECISION (parmtype))
+ {
+ case 8: OB_PUTC ('c'); return;
+ case 16: OB_PUTC ('s'); return;
+ case 32: OB_PUTC ('i'); return;
+ case 64: OB_PUTC ('x'); return;
+ }
+ }
+ }
+
parmtype = TYPE_MAIN_VARIANT (parmtype);
if (parmtype == integer_type_node
|| parmtype == unsigned_type_node)
used_extern_spec = 1;
}
sm = suspend_momentary ();
- *decl = start_decl (declarator, current_declspecs, initialized);
- cplus_decl_attributes (*decl, attributes, prefix_attributes);
+ *decl = start_decl (declarator, current_declspecs, initialized,
+ attributes, prefix_attributes);
return sm;
}
%}
}
current_declspecs = $1.t;
$<itype>5 = suspend_momentary ();
- $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1);
- cplus_decl_attributes ($<ttype>$, $4,
- /*prefix_attributes*/ NULL_TREE);
+ $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1,
+ $4, /*prefix_attributes*/ NULL_TREE);
}
init
{
initdcl:
declarator maybeasm maybe_attribute '='
- { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1);
- cplus_decl_attributes ($<ttype>$, $3, prefix_attributes); }
+ { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1,
+ $3, prefix_attributes); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); }
| declarator maybeasm maybe_attribute
- { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0);
- cplus_decl_attributes ($<ttype>$, $3, prefix_attributes);
+ { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0,
+ $3, prefix_attributes);
cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); }
;