Commit 7e585d16 by Zack Weinberg

c-parse.in (undeclared_variable_notice): Moved to c-typeck.c.

	* c-parse.in (undeclared_variable_notice): Moved to c-typeck.c.
	(primary: IDENTIFIER): Just call build_external_ref.
	* c-parse.y, c-parse.c, objc/objc-parse.y, objc/objc-parse.c:
	Regenerate.
	* c-lex.c (lastiddecl): Remove.
	(yylex): Replace all instances of lastiddecl with local
	variables.

	* c-typeck.c (build_external_ref): New function.  Treat decls
	with C_DECL_ANTICIPATED mostly the same as nonexistent decls.
	Look up the decl from the id here.  Call lookup_objc_ivar.
	* c-lang.c (lookup_objc_ivar): Stub.
	* objc/objc-act.c (lookup_objc_ivar): New function.

	* c-tree.h: Prototype lookup_objc_ivar and build_external_ref.
	* c-lex.h: Don't declare lastiddecl.

From-SVN: r34602
parent 2f103494
...@@ -171,6 +171,15 @@ build_objc_string (len, str) ...@@ -171,6 +171,15 @@ build_objc_string (len, str)
return NULL_TREE; return NULL_TREE;
} }
/* Used by c-typeck.c (build_external_ref), but only for objc. */
tree
lookup_objc_ivar (id)
tree id ATTRIBUTE_UNUSED;
{
return 0;
}
/* Called at end of parsing, but before end-of-file processing. */ /* Called at end of parsing, but before end-of-file processing. */
void void
......
...@@ -126,12 +126,6 @@ put_back (ch) ...@@ -126,12 +126,6 @@ put_back (ch)
int linemode; int linemode;
/* the declaration found for the last IDENTIFIER token read in.
yylex must look this up to detect typedefs, which get token type TYPENAME,
so it is left around in case the identifier is not a typedef but is
used in a context which makes it a reference to a variable. */
tree lastiddecl;
extern int yydebug; extern int yydebug;
/* File used for outputting assembler code. */ /* File used for outputting assembler code. */
...@@ -1400,10 +1394,10 @@ yylex () ...@@ -1400,10 +1394,10 @@ yylex ()
/* Only return OBJECTNAME if it is a typedef. */ /* Only return OBJECTNAME if it is a typedef. */
if (doing_objc_thang && value == OBJECTNAME) if (doing_objc_thang && value == OBJECTNAME)
{ {
lastiddecl = lookup_name(yylval.ttype); tree decl = lookup_name(yylval.ttype);
if (lastiddecl == NULL_TREE if (decl == NULL_TREE
|| TREE_CODE (lastiddecl) != TYPE_DECL) || TREE_CODE (decl) != TYPE_DECL)
value = IDENTIFIER; value = IDENTIFIER;
} }
...@@ -1422,24 +1416,26 @@ yylex () ...@@ -1422,24 +1416,26 @@ yylex ()
if (value == IDENTIFIER) if (value == IDENTIFIER)
{ {
tree decl;
if (token_buffer[0] == '@') if (token_buffer[0] == '@')
error("invalid identifier `%s'", token_buffer); error("invalid identifier `%s'", token_buffer);
yylval.ttype = get_identifier (token_buffer); yylval.ttype = get_identifier (token_buffer);
lastiddecl = lookup_name (yylval.ttype); decl = lookup_name (yylval.ttype);
if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL) if (decl != 0 && TREE_CODE (decl) == TYPE_DECL)
value = TYPENAME; value = TYPENAME;
/* A user-invisible read-only initialized variable /* A user-invisible read-only initialized variable
should be replaced by its value. should be replaced by its value.
We handle only strings since that's the only case used in C. */ We handle only strings since that's the only case used in C. */
else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL else if (decl != 0 && TREE_CODE (decl) == VAR_DECL
&& DECL_IGNORED_P (lastiddecl) && DECL_IGNORED_P (decl)
&& TREE_READONLY (lastiddecl) && TREE_READONLY (decl)
&& DECL_INITIAL (lastiddecl) != 0 && DECL_INITIAL (decl) != 0
&& TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
{ {
tree stringval = DECL_INITIAL (lastiddecl); tree stringval = DECL_INITIAL (decl);
/* Copy the string value so that we won't clobber anything /* Copy the string value so that we won't clobber anything
if we put something in the TREE_CHAIN of this one. */ if we put something in the TREE_CHAIN of this one. */
......
...@@ -69,12 +69,6 @@ enum rid ...@@ -69,12 +69,6 @@ enum rid
It is indexed by a RID_... value. */ It is indexed by a RID_... value. */
extern tree ridpointers[(int) RID_MAX]; extern tree ridpointers[(int) RID_MAX];
/* the declaration found for the last IDENTIFIER token read in.
yylex must look this up to detect typedefs, which get token type TYPENAME,
so it is left around in case the identifier is not a typedef but is
used in a context which makes it a reference to a variable. */
extern tree lastiddecl;
extern char *token_buffer; /* Pointer to token buffer. */ extern char *token_buffer; /* Pointer to token buffer. */
extern tree make_pointer_declarator PARAMS ((tree, tree)); extern tree make_pointer_declarator PARAMS ((tree, tree));
......
...@@ -226,9 +226,6 @@ static tree prefix_attributes = NULL_TREE; ...@@ -226,9 +226,6 @@ static tree prefix_attributes = NULL_TREE;
/* Stack of saved values of current_declspecs and prefix_attributes. */ /* Stack of saved values of current_declspecs and prefix_attributes. */
static tree declspec_stack; static tree declspec_stack;
/* 1 if we explained undeclared var errors. */
static int undeclared_variable_notice;
/* For __extension__, save/restore the warning flags which are /* For __extension__, save/restore the warning flags which are
controlled by __extension__. */ controlled by __extension__. */
#define SAVE_WARN_FLAGS() \ #define SAVE_WARN_FLAGS() \
...@@ -628,169 +625,9 @@ expr_no_commas: ...@@ -628,169 +625,9 @@ expr_no_commas:
primary: primary:
IDENTIFIER IDENTIFIER
{ {
$$ = lastiddecl; if (yychar == YYEMPTY)
if (!$$ || $$ == error_mark_node) yychar = YYLEX;
{ $$ = build_external_ref ($1, yychar == '(');
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
ifobjc
tree decl;
if (objc_receiver_context
&& ! (objc_receiver_context
&& strcmp (IDENTIFIER_POINTER ($1), "super")))
/* we have a message to super */
$$ = get_super_receiver ();
else if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
else
end ifobjc
{
/* Ordinary implicit function declaration. */
$$ = implicitly_declare ($1);
assemble_external ($$);
TREE_USED ($$) = 1;
}
}
else if (current_function_decl == 0)
{
error ("`%s' undeclared here (not in a function)",
IDENTIFIER_POINTER ($1));
$$ = error_mark_node;
}
else
{
ifobjc
tree decl;
if (objc_receiver_context
&& ! strcmp (IDENTIFIER_POINTER ($1), "super"))
/* we have a message to super */
$$ = get_super_receiver ();
else if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
else
end ifobjc
{
if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
{
error ("`%s' undeclared (first use in this function)",
IDENTIFIER_POINTER ($1));
if (! undeclared_variable_notice)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
undeclared_variable_notice = 1;
}
}
$$ = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
}
}
}
else if (TREE_TYPE ($$) == error_mark_node)
$$ = error_mark_node;
else if (C_DECL_ANTICIPATED ($$))
{
/* The first time we see a build-in function used,
if it has not been declared. */
C_DECL_ANTICIPATED ($$) = 0;
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
/* Omit the implicit declaration we
would ordinarily do, so we don't lose
the actual built in type.
But print a diagnostic for the mismatch. */
ifobjc
if (objc_method_context
&& is_ivar (objc_ivar_chain, $1))
error ("Instance variable `%s' implicitly declared as function",
IDENTIFIER_POINTER (DECL_NAME ($$)));
else
end ifobjc
if (TREE_CODE ($$) != FUNCTION_DECL)
error ("`%s' implicitly declared as function",
IDENTIFIER_POINTER (DECL_NAME ($$)));
else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
!= TYPE_MODE (integer_type_node))
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE ($$))))
pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* If it really returns void, change that to int. */
if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
TREE_TYPE ($$)
= build_function_type (integer_type_node,
TYPE_ARG_TYPES (TREE_TYPE ($$)));
}
else
pedwarn ("built-in function `%s' used without declaration",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* Do what we would ordinarily do when a fn is used. */
assemble_external ($$);
TREE_USED ($$) = 1;
}
else
{
assemble_external ($$);
TREE_USED ($$) = 1;
ifobjc
/* we have a definition - still check if iVariable */
if (!objc_receiver_context
|| (objc_receiver_context
&& strcmp (IDENTIFIER_POINTER ($1), "super")))
{
tree decl;
if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (IDENTIFIER_LOCAL_VALUE ($1))
warning ("local declaration of `%s' hides instance variable",
IDENTIFIER_POINTER ($1));
else
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
}
}
else /* we have a message to super */
$$ = get_super_receiver ();
end ifobjc
}
if (TREE_CODE ($$) == CONST_DECL)
{
$$ = DECL_INITIAL ($$);
/* This is to prevent an enum whose value is 0
from being considered a null pointer constant. */
$$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
TREE_CONSTANT ($$) = 1;
}
} }
| CONSTANT | CONSTANT
| string | string
......
...@@ -201,9 +201,6 @@ static tree prefix_attributes = NULL_TREE; ...@@ -201,9 +201,6 @@ static tree prefix_attributes = NULL_TREE;
/* Stack of saved values of current_declspecs and prefix_attributes. */ /* Stack of saved values of current_declspecs and prefix_attributes. */
static tree declspec_stack; static tree declspec_stack;
/* 1 if we explained undeclared var errors. */
static int undeclared_variable_notice;
/* For __extension__, save/restore the warning flags which are /* For __extension__, save/restore the warning flags which are
controlled by __extension__. */ controlled by __extension__. */
#define SAVE_WARN_FLAGS() \ #define SAVE_WARN_FLAGS() \
...@@ -576,100 +573,9 @@ expr_no_commas: ...@@ -576,100 +573,9 @@ expr_no_commas:
primary: primary:
IDENTIFIER IDENTIFIER
{ {
$$ = lastiddecl; if (yychar == YYEMPTY)
if (!$$ || $$ == error_mark_node) yychar = YYLEX;
{ $$ = build_external_ref ($1, yychar == '(');
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
{
/* Ordinary implicit function declaration. */
$$ = implicitly_declare ($1);
assemble_external ($$);
TREE_USED ($$) = 1;
}
}
else if (current_function_decl == 0)
{
error ("`%s' undeclared here (not in a function)",
IDENTIFIER_POINTER ($1));
$$ = error_mark_node;
}
else
{
{
if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
{
error ("`%s' undeclared (first use in this function)",
IDENTIFIER_POINTER ($1));
if (! undeclared_variable_notice)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
undeclared_variable_notice = 1;
}
}
$$ = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
}
}
}
else if (TREE_TYPE ($$) == error_mark_node)
$$ = error_mark_node;
else if (C_DECL_ANTICIPATED ($$))
{
/* The first time we see a build-in function used,
if it has not been declared. */
C_DECL_ANTICIPATED ($$) = 0;
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
/* Omit the implicit declaration we
would ordinarily do, so we don't lose
the actual built in type.
But print a diagnostic for the mismatch. */
if (TREE_CODE ($$) != FUNCTION_DECL)
error ("`%s' implicitly declared as function",
IDENTIFIER_POINTER (DECL_NAME ($$)));
else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
!= TYPE_MODE (integer_type_node))
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE ($$))))
pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* If it really returns void, change that to int. */
if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
TREE_TYPE ($$)
= build_function_type (integer_type_node,
TYPE_ARG_TYPES (TREE_TYPE ($$)));
}
else
pedwarn ("built-in function `%s' used without declaration",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* Do what we would ordinarily do when a fn is used. */
assemble_external ($$);
TREE_USED ($$) = 1;
}
else
{
assemble_external ($$);
TREE_USED ($$) = 1;
}
if (TREE_CODE ($$) == CONST_DECL)
{
$$ = DECL_INITIAL ($$);
/* This is to prevent an enum whose value is 0
from being considered a null pointer constant. */
$$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
TREE_CONSTANT ($$) = 1;
}
} }
| CONSTANT | CONSTANT
| string | string
......
...@@ -163,6 +163,7 @@ extern tree maybe_building_objc_message_expr PARAMS ((void)); ...@@ -163,6 +163,7 @@ extern tree maybe_building_objc_message_expr PARAMS ((void));
extern tree maybe_objc_method_name PARAMS ((tree)); extern tree maybe_objc_method_name PARAMS ((tree));
extern int recognize_objc_keyword PARAMS ((void)); extern int recognize_objc_keyword PARAMS ((void));
extern tree build_objc_string PARAMS ((int, const char *)); extern tree build_objc_string PARAMS ((int, const char *));
extern tree lookup_objc_ivar PARAMS ((tree));
/* in c-parse.in */ /* in c-parse.in */
extern void c_parse_init PARAMS ((void)); extern void c_parse_init PARAMS ((void));
...@@ -263,6 +264,7 @@ extern tree default_conversion PARAMS ((tree)); ...@@ -263,6 +264,7 @@ extern tree default_conversion PARAMS ((tree));
extern tree build_component_ref PARAMS ((tree, tree)); extern tree build_component_ref PARAMS ((tree, tree));
extern tree build_indirect_ref PARAMS ((tree, const char *)); extern tree build_indirect_ref PARAMS ((tree, const char *));
extern tree build_array_ref PARAMS ((tree, tree)); extern tree build_array_ref PARAMS ((tree, tree));
extern tree build_external_ref PARAMS ((tree, int));
extern tree build_function_call PARAMS ((tree, tree)); extern tree build_function_call PARAMS ((tree, tree));
extern tree parser_build_binary_op PARAMS ((enum tree_code, extern tree parser_build_binary_op PARAMS ((enum tree_code,
tree, tree)); tree, tree));
......
...@@ -47,6 +47,9 @@ Boston, MA 02111-1307, USA. */ ...@@ -47,6 +47,9 @@ Boston, MA 02111-1307, USA. */
message within this initializer. */ message within this initializer. */
static int missing_braces_mentioned; static int missing_braces_mentioned;
/* 1 if we explained undeclared var errors. */
static int undeclared_variable_notice;
static tree qualify_type PARAMS ((tree, tree)); static tree qualify_type PARAMS ((tree, tree));
static int comp_target_types PARAMS ((tree, tree)); static int comp_target_types PARAMS ((tree, tree));
static int function_types_compatible_p PARAMS ((tree, tree)); static int function_types_compatible_p PARAMS ((tree, tree));
...@@ -1389,6 +1392,95 @@ build_array_ref (array, index) ...@@ -1389,6 +1392,95 @@ build_array_ref (array, index)
} }
} }
/* Build an external reference to identifier ID. FUN indicates
whether this will be used for a function call. */
tree
build_external_ref (id, fun)
tree id;
int fun;
{
tree ref;
tree decl = lookup_name (id);
tree objc_ivar = lookup_objc_ivar (id);
if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
{
if (objc_ivar)
ref = objc_ivar;
else if (fun)
{
if (!decl || decl == error_mark_node)
/* Ordinary implicit function declaration. */
ref = implicitly_declare (id);
else
{
/* Implicit declaration of built-in function. Don't
change the built-in declaration, but don't let this
go by silently, either. */
pedwarn ("implicit declaration of function `%s'",
IDENTIFIER_POINTER (DECL_NAME (decl)));
C_DECL_ANTICIPATED (decl) = 0; /* only issue this warning once */
ref = decl;
}
}
else
{
/* Reference to undeclared variable, including reference to
builtin outside of function-call context. */
if (current_function_decl == 0)
error ("`%s' undeclared here (not in a function)",
IDENTIFIER_POINTER (id));
else
{
if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS (id) != current_function_decl)
{
error ("`%s' undeclared (first use in this function)",
IDENTIFIER_POINTER (id));
if (! undeclared_variable_notice)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
undeclared_variable_notice = 1;
}
}
IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node;
IDENTIFIER_ERROR_LOCUS (id) = current_function_decl;
}
return error_mark_node;
}
}
else
{
/* Properly declared variable or function reference. */
if (!objc_ivar)
ref = decl;
else if (decl != objc_ivar && IDENTIFIER_LOCAL_VALUE (id))
{
warning ("local declaration of `%s' hides instance variable",
IDENTIFIER_POINTER (id));
ref = decl;
}
else
ref = objc_ivar;
}
if (TREE_TYPE (ref) == error_mark_node)
return error_mark_node;
assemble_external (ref);
TREE_USED (ref) = 1;
if (TREE_CODE (ref) == CONST_DECL)
{
ref = DECL_INITIAL (ref);
TREE_CONSTANT (ref) = 1;
}
return ref;
}
/* Build a function call to function FUNCTION with parameters PARAMS. /* Build a function call to function FUNCTION with parameters PARAMS.
PARAMS is a list--a chain of TREE_LIST nodes--in which the PARAMS is a list--a chain of TREE_LIST nodes--in which the
TREE_VALUE of each node is a parameter-expression. TREE_VALUE of each node is a parameter-expression.
......
...@@ -8614,3 +8614,24 @@ objc_act_parse_init () ...@@ -8614,3 +8614,24 @@ objc_act_parse_init ()
ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table); ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table); ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
} }
/* Look up ID as an instance variable. */
tree
lookup_objc_ivar (id)
tree id;
{
tree decl;
if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
/* we have a message to super */
return get_super_receiver ();
else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
{
if (is_private (decl))
return error_mark_node;
else
return build_ivar_reference (id);
}
else
return 0;
}
...@@ -213,9 +213,6 @@ static tree prefix_attributes = NULL_TREE; ...@@ -213,9 +213,6 @@ static tree prefix_attributes = NULL_TREE;
/* Stack of saved values of current_declspecs and prefix_attributes. */ /* Stack of saved values of current_declspecs and prefix_attributes. */
static tree declspec_stack; static tree declspec_stack;
/* 1 if we explained undeclared var errors. */
static int undeclared_variable_notice;
/* For __extension__, save/restore the warning flags which are /* For __extension__, save/restore the warning flags which are
controlled by __extension__. */ controlled by __extension__. */
#define SAVE_WARN_FLAGS() \ #define SAVE_WARN_FLAGS() \
...@@ -607,161 +604,9 @@ expr_no_commas: ...@@ -607,161 +604,9 @@ expr_no_commas:
primary: primary:
IDENTIFIER IDENTIFIER
{ {
$$ = lastiddecl; if (yychar == YYEMPTY)
if (!$$ || $$ == error_mark_node) yychar = YYLEX;
{ $$ = build_external_ref ($1, yychar == '(');
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
tree decl;
if (objc_receiver_context
&& ! (objc_receiver_context
&& strcmp (IDENTIFIER_POINTER ($1), "super")))
/* we have a message to super */
$$ = get_super_receiver ();
else if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
else
{
/* Ordinary implicit function declaration. */
$$ = implicitly_declare ($1);
assemble_external ($$);
TREE_USED ($$) = 1;
}
}
else if (current_function_decl == 0)
{
error ("`%s' undeclared here (not in a function)",
IDENTIFIER_POINTER ($1));
$$ = error_mark_node;
}
else
{
tree decl;
if (objc_receiver_context
&& ! strcmp (IDENTIFIER_POINTER ($1), "super"))
/* we have a message to super */
$$ = get_super_receiver ();
else if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
else
{
if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
{
error ("`%s' undeclared (first use in this function)",
IDENTIFIER_POINTER ($1));
if (! undeclared_variable_notice)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
undeclared_variable_notice = 1;
}
}
$$ = error_mark_node;
/* Prevent repeated error messages. */
IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
}
}
}
else if (TREE_TYPE ($$) == error_mark_node)
$$ = error_mark_node;
else if (C_DECL_ANTICIPATED ($$))
{
/* The first time we see a build-in function used,
if it has not been declared. */
C_DECL_ANTICIPATED ($$) = 0;
if (yychar == YYEMPTY)
yychar = YYLEX;
if (yychar == '(')
{
/* Omit the implicit declaration we
would ordinarily do, so we don't lose
the actual built in type.
But print a diagnostic for the mismatch. */
if (objc_method_context
&& is_ivar (objc_ivar_chain, $1))
error ("Instance variable `%s' implicitly declared as function",
IDENTIFIER_POINTER (DECL_NAME ($$)));
else
if (TREE_CODE ($$) != FUNCTION_DECL)
error ("`%s' implicitly declared as function",
IDENTIFIER_POINTER (DECL_NAME ($$)));
else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
!= TYPE_MODE (integer_type_node))
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE ($$))))
pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* If it really returns void, change that to int. */
if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
TREE_TYPE ($$)
= build_function_type (integer_type_node,
TYPE_ARG_TYPES (TREE_TYPE ($$)));
}
else
pedwarn ("built-in function `%s' used without declaration",
IDENTIFIER_POINTER (DECL_NAME ($$)));
/* Do what we would ordinarily do when a fn is used. */
assemble_external ($$);
TREE_USED ($$) = 1;
}
else
{
assemble_external ($$);
TREE_USED ($$) = 1;
/* we have a definition - still check if iVariable */
if (!objc_receiver_context
|| (objc_receiver_context
&& strcmp (IDENTIFIER_POINTER ($1), "super")))
{
tree decl;
if (objc_method_context
&& (decl = is_ivar (objc_ivar_chain, $1)))
{
if (IDENTIFIER_LOCAL_VALUE ($1))
warning ("local declaration of `%s' hides instance variable",
IDENTIFIER_POINTER ($1));
else
{
if (is_private (decl))
$$ = error_mark_node;
else
$$ = build_ivar_reference ($1);
}
}
}
else /* we have a message to super */
$$ = get_super_receiver ();
}
if (TREE_CODE ($$) == CONST_DECL)
{
$$ = DECL_INITIAL ($$);
/* This is to prevent an enum whose value is 0
from being considered a null pointer constant. */
$$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
TREE_CONSTANT ($$) = 1;
}
} }
| CONSTANT | CONSTANT
| string | string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment