1987-04-29 10:22:07 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*
|
|
|
|
* Author: Ceriel J.H. Jacobs
|
|
|
|
*/
|
|
|
|
|
1986-03-26 15:11:02 +00:00
|
|
|
/* D E F I N I T I O N M E C H A N I S M */
|
|
|
|
|
1994-06-24 14:02:31 +00:00
|
|
|
/* $Id$ */
|
1987-04-29 10:22:07 +00:00
|
|
|
|
2006-07-26 17:10:30 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "parameters.h"
|
1986-05-01 19:06:53 +00:00
|
|
|
#include "debug.h"
|
1986-03-26 15:11:02 +00:00
|
|
|
|
1986-03-29 01:04:49 +00:00
|
|
|
#include <assert.h>
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "alloc.h"
|
|
|
|
#include "em_arith.h"
|
|
|
|
#include "em_label.h"
|
|
|
|
#include "em_code.h"
|
1986-04-21 17:27:06 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
|
|
|
|
#include "typequiv.h"
|
1987-07-30 13:37:39 +00:00
|
|
|
#include "LLlex.h"
|
1986-04-08 18:15:46 +00:00
|
|
|
#include "main.h"
|
1986-03-26 15:11:02 +00:00
|
|
|
#include "def.h"
|
1986-04-02 17:34:21 +00:00
|
|
|
#include "type.h"
|
1986-03-26 15:11:02 +00:00
|
|
|
#include "idf.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "print.h"
|
1986-03-26 15:11:02 +00:00
|
|
|
#include "scope.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "lookup.h"
|
1986-04-06 17:42:56 +00:00
|
|
|
#include "node.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "misc.h"
|
1986-05-28 18:36:51 +00:00
|
|
|
#include "Lpars.h"
|
1988-02-09 11:41:08 +00:00
|
|
|
#include "warning.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "error.h"
|
|
|
|
|
1986-04-21 17:27:06 +00:00
|
|
|
|
1988-10-13 15:43:23 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
static void internal(register char *c)
|
1988-03-23 17:44:25 +00:00
|
|
|
{
|
2019-03-01 17:39:25 +00:00
|
|
|
if (options['x'])
|
|
|
|
{
|
1988-03-23 17:44:25 +00:00
|
|
|
C_exp(c);
|
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
else
|
|
|
|
C_inp(c);
|
1988-03-23 17:44:25 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
static void DefInFront(register struct def *df)
|
1986-10-06 20:36:30 +00:00
|
|
|
{
|
|
|
|
/* Put definition "df" in front of the list of definitions
|
2019-03-01 17:39:25 +00:00
|
|
|
in its scope.
|
|
|
|
This is neccessary because in some cases the order in this
|
|
|
|
list is important.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df1 = df->df_scope->sc_def;
|
1986-10-06 20:36:30 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (df1 != df)
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* Definition "df" is not in front of the list
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
|
|
|
while (df1)
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* Find definition "df"
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
|
|
|
if (df1->df_nextinscope == df)
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* It already was in the list. Remove it
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
df1->df_nextinscope = df->df_nextinscope;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
df1 = df1->df_nextinscope;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now put it in front
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
df->df_nextinscope = df->df_scope->sc_def;
|
|
|
|
df->df_scope->sc_def = df;
|
|
|
|
}
|
|
|
|
}
|
1986-03-27 17:37:41 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *MkDef(register struct idf *id, register struct scope *scope, int kind)
|
1986-04-18 17:53:47 +00:00
|
|
|
{
|
|
|
|
/* Create a new definition structure in scope "scope", with
|
2019-03-01 17:39:25 +00:00
|
|
|
id "id" and kind "kind".
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
1986-04-18 17:53:47 +00:00
|
|
|
|
|
|
|
df = new_def();
|
|
|
|
df->df_idf = id;
|
|
|
|
df->df_scope = scope;
|
|
|
|
df->df_kind = kind;
|
1987-07-16 19:51:40 +00:00
|
|
|
df->df_next = id->id_def;
|
1986-04-18 17:53:47 +00:00
|
|
|
id->id_def = df;
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind == D_ERROR || kind == D_FORWARD)
|
|
|
|
df->df_type = error_type;
|
|
|
|
if (kind & (D_TYPE | D_PROCEDURE | D_CONST))
|
|
|
|
{
|
1987-11-27 14:24:46 +00:00
|
|
|
df->df_flags = D_DEFINED;
|
|
|
|
}
|
1986-04-18 17:53:47 +00:00
|
|
|
|
|
|
|
/* enter the definition in the list of definitions in this scope
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
1986-04-18 17:53:47 +00:00
|
|
|
df->df_nextinscope = scope->sc_def;
|
|
|
|
scope->sc_def = df;
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def *define(register struct idf *id, register struct scope *scope, int kind)
|
1986-03-26 15:11:02 +00:00
|
|
|
{
|
|
|
|
/* Declare an identifier in a scope, but first check if it
|
2019-03-01 17:39:25 +00:00
|
|
|
already has been defined.
|
|
|
|
If so, then check for the cases in which this is legal,
|
|
|
|
and otherwise give an error message.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
1986-03-26 15:11:02 +00:00
|
|
|
|
1988-09-20 13:31:57 +00:00
|
|
|
DO_DEBUG(options['S'], print("define %s, %x\n", id->id_text, kind));
|
1987-11-11 13:10:08 +00:00
|
|
|
df = lookup(id, scope, D_IMPORT, 0);
|
2019-03-01 17:39:25 +00:00
|
|
|
if ( /* Already in this scope */
|
|
|
|
df)
|
|
|
|
{
|
|
|
|
switch (df->df_kind)
|
|
|
|
{
|
1987-10-30 09:19:23 +00:00
|
|
|
case D_INUSE:
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind != D_INUSE && kind != D_ERROR)
|
|
|
|
{
|
|
|
|
error(
|
|
|
|
"identifier \"%s\" already used; may not be redefined in this scope",
|
|
|
|
df->df_idf->id_text);
|
1989-04-04 14:53:48 +00:00
|
|
|
df->df_kind = D_ERROR;
|
|
|
|
break;
|
1987-10-30 09:19:23 +00:00
|
|
|
}
|
|
|
|
return df;
|
|
|
|
|
1986-03-26 15:11:02 +00:00
|
|
|
case D_HIDDEN:
|
1986-06-04 09:01:48 +00:00
|
|
|
/* An opaque type. We may now have found the
|
2019-03-01 17:39:25 +00:00
|
|
|
definition of this type.
|
|
|
|
*/
|
|
|
|
if (kind == D_TYPE && df->df_scope == CurrentScope
|
|
|
|
&& !DefinitionModule)
|
|
|
|
{
|
1986-05-28 18:36:51 +00:00
|
|
|
df->df_kind = D_TYPE;
|
1986-03-26 15:11:02 +00:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
break;
|
1986-04-28 18:06:58 +00:00
|
|
|
|
1986-04-11 11:57:19 +00:00
|
|
|
case D_FORWMODULE:
|
1986-06-04 09:01:48 +00:00
|
|
|
/* A forward reference to a module. We may have found
|
2019-03-01 17:39:25 +00:00
|
|
|
another one, or we may have found the definition
|
|
|
|
for this module.
|
|
|
|
*/
|
|
|
|
if (kind & (D_FORWMODULE | D_FORWARD))
|
|
|
|
{
|
1986-04-12 02:21:24 +00:00
|
|
|
return df;
|
|
|
|
}
|
1986-04-28 18:06:58 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind == D_MODULE)
|
|
|
|
{
|
1986-04-12 02:21:24 +00:00
|
|
|
FreeNode(df->for_node);
|
1986-04-28 18:06:58 +00:00
|
|
|
df->mod_vis = df->for_vis;
|
1986-04-11 11:57:19 +00:00
|
|
|
df->df_kind = kind;
|
1986-05-28 18:36:51 +00:00
|
|
|
DefInFront(df);
|
1986-04-11 11:57:19 +00:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
break;
|
1986-04-28 18:06:58 +00:00
|
|
|
|
1986-11-28 11:59:08 +00:00
|
|
|
case D_TYPE:
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind == D_FORWTYPE)
|
|
|
|
return df;
|
1986-11-28 11:59:08 +00:00
|
|
|
break;
|
1986-11-26 16:40:45 +00:00
|
|
|
case D_FORWTYPE:
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind & (D_FORWTYPE | D_TYPE))
|
|
|
|
return df;
|
1989-04-04 14:53:48 +00:00
|
|
|
error("identifier \"%s\" must be a type", id->id_text);
|
|
|
|
df->df_kind = D_ERROR;
|
|
|
|
break;
|
1986-04-11 11:57:19 +00:00
|
|
|
case D_FORWARD:
|
1986-06-04 09:01:48 +00:00
|
|
|
/* A forward reference, for which we may now have
|
2019-03-01 17:39:25 +00:00
|
|
|
found a definition.
|
|
|
|
*/
|
|
|
|
if (!(kind & (D_FORWARD | D_FORWMODULE)))
|
|
|
|
{
|
1986-04-12 02:21:24 +00:00
|
|
|
FreeNode(df->for_node);
|
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
df->df_kind = D_ERROR; /* avoiding error message */
|
1989-04-04 14:53:48 +00:00
|
|
|
break;
|
1986-03-26 15:11:02 +00:00
|
|
|
}
|
1986-04-28 18:06:58 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind != D_ERROR && df->df_kind != D_ERROR)
|
|
|
|
{
|
1986-06-04 09:01:48 +00:00
|
|
|
/* Avoid spurious error messages
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
|
|
|
error("identifier \"%s\" already declared", id->id_text);
|
1986-04-02 17:34:21 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
if (df->df_scope == scope || df->df_kind == D_ERROR)
|
|
|
|
{
|
1989-04-04 14:53:48 +00:00
|
|
|
df->df_kind = kind;
|
2019-03-01 17:39:25 +00:00
|
|
|
if (kind & (D_TYPE | D_PROCEDURE | D_CONST))
|
|
|
|
{
|
1989-04-04 14:53:48 +00:00
|
|
|
df->df_flags = D_DEFINED;
|
|
|
|
}
|
1986-04-28 18:06:58 +00:00
|
|
|
|
1989-04-04 14:53:48 +00:00
|
|
|
return df;
|
|
|
|
}
|
1986-03-26 15:11:02 +00:00
|
|
|
}
|
1986-04-28 18:06:58 +00:00
|
|
|
|
1986-04-18 17:53:47 +00:00
|
|
|
return MkDef(id, scope, kind);
|
1986-03-26 15:11:02 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void end_definition_list(register struct def **pdf)
|
1986-04-03 17:41:26 +00:00
|
|
|
{
|
|
|
|
/* Remove all imports from a definition module. This is
|
2019-03-01 17:39:25 +00:00
|
|
|
neccesary because the implementation module might import
|
|
|
|
them again.
|
|
|
|
Also, mark all other definitions "QUALIFIED EXPORT".
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
1986-04-03 17:41:26 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
while ( (df = *pdf) )
|
|
|
|
{
|
|
|
|
if (df->df_kind & D_IMPORTED)
|
|
|
|
{
|
|
|
|
if (!(df->df_flags & D_USED))
|
|
|
|
{
|
|
|
|
warning(W_ORDINARY, "identifier \"%s\" imported but not used",
|
|
|
|
df->df_idf->id_text);
|
1988-02-09 11:41:08 +00:00
|
|
|
}
|
1986-06-04 09:01:48 +00:00
|
|
|
RemoveFromIdList(df);
|
1986-04-12 02:21:24 +00:00
|
|
|
*pdf = df->df_nextinscope;
|
|
|
|
free_def(df);
|
1986-04-03 17:41:26 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
else
|
|
|
|
{
|
1988-02-09 11:41:08 +00:00
|
|
|
df->df_flags |= D_QEXPORTED;
|
1986-04-12 02:21:24 +00:00
|
|
|
pdf = &(df->df_nextinscope);
|
1986-04-03 17:41:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void RemoveFromIdList(register struct def *df)
|
1986-04-03 17:41:26 +00:00
|
|
|
{
|
|
|
|
/* Remove definition "df" from the definition list
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct idf *id = df->df_idf;
|
|
|
|
register struct def *df1;
|
1986-04-03 17:41:26 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if ((df1 = id->id_def) == df)
|
|
|
|
id->id_def = df->df_next;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (df1->df_next != df)
|
|
|
|
{
|
1987-07-16 19:51:40 +00:00
|
|
|
assert(df1->df_next != 0);
|
|
|
|
df1 = df1->df_next;
|
1986-04-03 17:41:26 +00:00
|
|
|
}
|
1987-07-16 19:51:40 +00:00
|
|
|
df1->df_next = df->df_next;
|
1986-04-03 17:41:26 +00:00
|
|
|
}
|
|
|
|
}
|
1986-04-15 17:51:53 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def * DeclProc(int type, register struct idf *id)
|
1986-04-21 17:27:06 +00:00
|
|
|
{
|
|
|
|
/* A procedure is declared, either in a definition or a program
|
2019-03-01 17:39:25 +00:00
|
|
|
module. Create a def structure for it (if neccessary).
|
|
|
|
Also create a name for it.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df;
|
|
|
|
register struct scope *scope;
|
1986-06-06 02:22:09 +00:00
|
|
|
static int nmcount;
|
1986-04-21 17:27:06 +00:00
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
assert(type & (D_PROCEDURE | D_PROCHEAD));
|
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (type == D_PROCHEAD)
|
|
|
|
{
|
1986-04-21 17:27:06 +00:00
|
|
|
/* In a definition module
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
df = define(id, CurrentScope, type);
|
1987-08-10 21:43:47 +00:00
|
|
|
df->for_node = dot2leaf(Name);
|
1987-10-19 11:28:37 +00:00
|
|
|
df->df_flags |= D_USED | D_DEFINED;
|
2019-03-01 17:39:25 +00:00
|
|
|
if (CurrentScope->sc_definedby->df_flags & D_FOREIGN)
|
|
|
|
{
|
1991-03-12 16:52:00 +00:00
|
|
|
df->prc_name = id->id_text;
|
1987-04-29 10:22:07 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
sprint(buf, "%s_%s", CurrentScope->sc_name, id->id_text);
|
|
|
|
df->prc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
1987-04-29 10:22:07 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
if (CurrVis == Defined->mod_vis)
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* The current module will define this routine.
|
2019-03-01 17:39:25 +00:00
|
|
|
make sure the name is exported.
|
|
|
|
*/
|
1991-03-12 16:52:00 +00:00
|
|
|
C_exp(df->prc_name);
|
1986-10-06 20:36:30 +00:00
|
|
|
}
|
1986-04-21 17:27:06 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
else
|
|
|
|
{
|
1987-11-11 13:10:08 +00:00
|
|
|
df = lookup(id, CurrentScope, D_IMPORTED, 0);
|
2019-03-01 17:39:25 +00:00
|
|
|
if (df && df->df_kind == D_PROCHEAD)
|
|
|
|
{
|
1986-04-21 17:27:06 +00:00
|
|
|
/* C_exp already generated when we saw the definition
|
2019-03-01 17:39:25 +00:00
|
|
|
in the definition module
|
|
|
|
*/
|
1986-05-28 18:36:51 +00:00
|
|
|
DefInFront(df);
|
1986-04-21 17:27:06 +00:00
|
|
|
}
|
2019-03-01 17:39:25 +00:00
|
|
|
else
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
df = define(id, CurrentScope, type);
|
2019-03-01 17:39:25 +00:00
|
|
|
sprint(buf, "_%d_%s", ++nmcount, id->id_text);
|
|
|
|
df->prc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
1988-03-23 17:44:25 +00:00
|
|
|
internal(buf);
|
1987-10-19 11:28:37 +00:00
|
|
|
df->df_flags |= D_DEFINED;
|
1986-04-21 17:27:06 +00:00
|
|
|
}
|
1986-10-06 20:36:30 +00:00
|
|
|
open_scope(OPENSCOPE);
|
|
|
|
scope = CurrentScope;
|
1991-03-12 16:52:00 +00:00
|
|
|
scope->sc_name = df->prc_name;
|
1986-10-06 20:36:30 +00:00
|
|
|
scope->sc_definedby = df;
|
1986-04-21 17:27:06 +00:00
|
|
|
}
|
1987-08-24 11:42:37 +00:00
|
|
|
df->prc_vis = CurrVis;
|
1986-04-21 17:27:06 +00:00
|
|
|
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void EndProc(register struct def *df, struct idf *id)
|
1986-05-28 18:36:51 +00:00
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* The end of a procedure declaration.
|
2019-03-01 17:39:25 +00:00
|
|
|
Check that the closing identifier matches the name of the
|
|
|
|
procedure, close the scope, and check that a function
|
|
|
|
procedure has at least one RETURN statement.
|
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
extern int return_occurred;
|
1986-05-28 18:36:51 +00:00
|
|
|
|
1986-10-06 20:36:30 +00:00
|
|
|
match_id(id, df->df_idf);
|
2019-03-01 17:39:25 +00:00
|
|
|
close_scope(SC_CHKFORW | SC_REVERSE);
|
|
|
|
if (!return_occurred && ResultType(df->df_type))
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
error("function procedure %s does not return a value",
|
2019-03-01 17:39:25 +00:00
|
|
|
df->df_idf->id_text);
|
1986-05-28 18:36:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
struct def * DefineLocalModule(struct idf *id)
|
1986-06-17 12:04:05 +00:00
|
|
|
{
|
|
|
|
/* Create a definition for a local module. Also give it
|
2019-03-01 17:39:25 +00:00
|
|
|
a name to be used for code generation.
|
|
|
|
*/
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct def *df = define(id, CurrentScope, D_MODULE);
|
|
|
|
register struct scope *sc;
|
1986-06-17 12:04:05 +00:00
|
|
|
static int modulecount = 0;
|
|
|
|
char buf[256];
|
|
|
|
extern int proclevel;
|
|
|
|
|
1988-03-23 17:44:25 +00:00
|
|
|
sprint(buf, "_%d%s_", ++modulecount, id->id_text);
|
1986-06-17 12:04:05 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (!df->mod_vis)
|
|
|
|
{
|
1986-06-17 12:04:05 +00:00
|
|
|
/* We never saw the name of this module before. Create a
|
2019-03-01 17:39:25 +00:00
|
|
|
scope for it.
|
|
|
|
*/
|
|
|
|
open_scope(CLOSEDSCOPE);
|
|
|
|
df->mod_vis = CurrVis;
|
1986-06-17 12:04:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CurrVis = df->mod_vis;
|
|
|
|
|
|
|
|
sc = CurrentScope;
|
|
|
|
sc->sc_level = proclevel;
|
|
|
|
sc->sc_definedby = df;
|
|
|
|
sc->sc_name = Salloc(buf, (unsigned) (strlen(buf) + 1));
|
|
|
|
|
|
|
|
/* Create a type for it
|
2019-03-01 17:39:25 +00:00
|
|
|
*/
|
1986-11-26 16:40:45 +00:00
|
|
|
df->df_type = standard_type(T_RECORD, 1, (arith) 0);
|
1986-08-26 14:33:24 +00:00
|
|
|
df->df_type->rec_scope = sc;
|
1986-06-17 12:04:05 +00:00
|
|
|
|
|
|
|
/* Generate code that indicates that the initialization procedure
|
2019-03-01 17:39:25 +00:00
|
|
|
for this module is local.
|
|
|
|
*/
|
1988-03-23 17:44:25 +00:00
|
|
|
internal(buf);
|
1986-06-17 12:04:05 +00:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
void CheckWithDef(register struct def *df, struct type *tp)
|
1986-10-06 20:36:30 +00:00
|
|
|
{
|
|
|
|
/* Check the header of a procedure declaration against a
|
2019-03-01 17:39:25 +00:00
|
|
|
possible earlier definition in the definition module.
|
|
|
|
*/
|
1986-10-06 20:36:30 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (df->df_kind == D_PROCHEAD && df->df_type && df->df_type != error_type)
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
/* We already saw a definition of this type
|
2019-03-01 17:39:25 +00:00
|
|
|
in the definition module.
|
|
|
|
*/
|
1987-10-14 12:34:47 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
if (!TstProcEquiv(tp, df->df_type))
|
|
|
|
{
|
1986-10-06 20:36:30 +00:00
|
|
|
error("inconsistent procedure declaration for \"%s\"",
|
2019-03-01 17:39:25 +00:00
|
|
|
df->df_idf->id_text);
|
1986-10-06 20:36:30 +00:00
|
|
|
}
|
|
|
|
FreeType(df->df_type);
|
1987-11-03 12:44:09 +00:00
|
|
|
df->df_kind = D_PROCEDURE;
|
1986-10-06 20:36:30 +00:00
|
|
|
}
|
|
|
|
df->df_type = tp;
|
|
|
|
}
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
#ifdef DEBUG
|
2019-05-10 17:09:03 +00:00
|
|
|
void PrDef(register struct def *df)
|
1986-04-15 17:51:53 +00:00
|
|
|
{
|
1986-05-01 19:06:53 +00:00
|
|
|
print("n: %s, k: %d\n", df->df_idf->id_text, df->df_kind);
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
1991-12-17 14:36:35 +00:00
|
|
|
#endif /* DEBUG */
|