newer version, safety commit
This commit is contained in:
parent
66c571d217
commit
b89155a64a
8 changed files with 103 additions and 49 deletions
|
@ -4,6 +4,7 @@ static char *RcsId = "$Header$";
|
||||||
|
|
||||||
#include <alloc.h>
|
#include <alloc.h>
|
||||||
#include <em_arith.h>
|
#include <em_arith.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "f_info.h"
|
#include "f_info.h"
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
|
@ -179,7 +180,7 @@ again:
|
||||||
return tk->tk_symb = ch;
|
return tk->tk_symb = ch;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
crash("bad STCOMP");
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
case STIDF:
|
case STIDF:
|
||||||
|
@ -373,7 +374,7 @@ Sdec:
|
||||||
|
|
||||||
case STCHAR:
|
case STCHAR:
|
||||||
default:
|
default:
|
||||||
crash("bad character class %d", class(ch));
|
assert(0);
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,12 @@ TypeDeclaration
|
||||||
}:
|
}:
|
||||||
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
|
IDENT { df = define(dot.TOK_IDF, CurrentScope, D_TYPE); }
|
||||||
'=' type(&tp)
|
'=' type(&tp)
|
||||||
{ df->df_type = tp; }
|
{ df->df_type = tp;
|
||||||
|
if ((df->df_flags&D_EXPORTED) &&
|
||||||
|
tp->tp_fund == ENUMERATION) {
|
||||||
|
exprt_literals(tp->enm_enums, enclosing(currscope));
|
||||||
|
}
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
type(struct type **ptp;):
|
type(struct type **ptp;):
|
||||||
|
@ -338,7 +343,7 @@ PointerType(struct type **ptp;)
|
||||||
}
|
}
|
||||||
else tp = df->df_type;
|
else tp = df->df_type;
|
||||||
}
|
}
|
||||||
| %if (df = lookfor(dot.TOK_IDF, 0), df->df_kind == D_MODULE)
|
| %if (df = lookfor(dot.TOK_IDF, currscope, 0), df->df_kind == D_MODULE)
|
||||||
type(&tp)
|
type(&tp)
|
||||||
|
|
|
|
||||||
IDENT
|
IDENT
|
||||||
|
|
|
@ -38,8 +38,8 @@ struct field {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct import {
|
struct import {
|
||||||
int im_scopenr; /* Scope number from which imported */
|
struct def *im_def; /* Scope number from which imported */
|
||||||
#define imp_scopenr df_value.df_import.im_scopenr
|
#define imp_def df_value.df_import.im_def
|
||||||
};
|
};
|
||||||
|
|
||||||
struct def { /* list of definitions for a name */
|
struct def { /* list of definitions for a name */
|
||||||
|
|
|
@ -8,6 +8,7 @@ static char *RcsId = "$Header$";
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "Lpars.h"
|
#include "Lpars.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
|
#include "type.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
@ -60,7 +61,9 @@ define(id, scope, kind)
|
||||||
df->df_kind = kind;
|
df->df_kind = kind;
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
error("identifier \"%s\" already declared", id->id_text);
|
if (kind != D_ERROR) {
|
||||||
|
error("identifier \"%s\" already declared", id->id_text);
|
||||||
|
}
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
df = new_def();
|
df = new_def();
|
||||||
|
@ -98,12 +101,9 @@ lookup(id, scope)
|
||||||
while (df) {
|
while (df) {
|
||||||
if (df->df_scope == scope) {
|
if (df->df_scope == scope) {
|
||||||
if (df->df_kind == D_IMPORT) {
|
if (df->df_kind == D_IMPORT) {
|
||||||
df = lookup(id, df->imp_scopenr);
|
df = df->imp_def;
|
||||||
assert(df != 0);
|
assert(df != 0);
|
||||||
return df;
|
return df;
|
||||||
/* ??? But this does damage to the self-
|
|
||||||
organizing character of the list
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
if (df1) {
|
if (df1) {
|
||||||
df1->next = df->next;
|
df1->next = df->next;
|
||||||
|
@ -118,14 +118,14 @@ lookup(id, scope)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From the current scope, the list of identifiers "ids" is
|
|
||||||
exported. Note this fact. If the export is not qualified, make
|
|
||||||
all the "ids" visible in the enclosing scope by defining them
|
|
||||||
in this scope as "imported".
|
|
||||||
*/
|
|
||||||
Export(ids, qualified)
|
Export(ids, qualified)
|
||||||
register struct id_list *ids;
|
register struct id_list *ids;
|
||||||
{
|
{
|
||||||
|
/* From the current scope, the list of identifiers "ids" is
|
||||||
|
exported. Note this fact. If the export is not qualified, make
|
||||||
|
all the "ids" visible in the enclosing scope by defining them
|
||||||
|
in this scope as "imported".
|
||||||
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
|
|
||||||
while (ids) {
|
while (ids) {
|
||||||
|
@ -142,53 +142,88 @@ Export(ids, qualified)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "ids" is a list of imported identifiers.
|
|
||||||
If "id" is a null-pointer, the identifiers are imported from the
|
|
||||||
enclosing scope. Otherwise they are imported from the module
|
|
||||||
indicated by "id", ehich must be visible in the enclosing scope.
|
|
||||||
An exception must be made for imports of the Compilation Unit.
|
|
||||||
This case is indicated by the value 0 of the flag "local".
|
|
||||||
In this case, if "id" is a null pointer, the "ids" identifiers
|
|
||||||
are all module identifiers. Their Definition Modules must be read.
|
|
||||||
Otherwise "id" is a module identifier whose Definition Module must
|
|
||||||
be read. "ids" then represents a list of identifiers defined in
|
|
||||||
this module.
|
|
||||||
*/
|
|
||||||
Import(ids, id, local)
|
Import(ids, id, local)
|
||||||
register struct id_list *ids;
|
register struct id_list *ids;
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
{
|
{
|
||||||
|
/* "ids" is a list of imported identifiers.
|
||||||
|
If "id" is a null-pointer, the identifiers are imported from the
|
||||||
|
enclosing scope. Otherwise they are imported from the module
|
||||||
|
indicated by "id", ehich must be visible in the enclosing scope.
|
||||||
|
An exception must be made for imports of the Compilation Unit.
|
||||||
|
This case is indicated by the value 0 of the flag "local".
|
||||||
|
In this case, if "id" is a null pointer, the "ids" identifiers
|
||||||
|
are all module identifiers. Their Definition Modules must be
|
||||||
|
read. Otherwise "id" is a module identifier whose Definition
|
||||||
|
Module must be read. "ids" then represents a list of
|
||||||
|
identifiers defined in this module.
|
||||||
|
*/
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
int scope;
|
int scope;
|
||||||
int kind;
|
int kind;
|
||||||
|
int imp_kind;
|
||||||
|
#define FROM_MODULE 0
|
||||||
|
#define FROM_ENCLOSING 1
|
||||||
struct def *lookfor();
|
struct def *lookfor();
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
kind = D_IMPORT;
|
kind = D_IMPORT;
|
||||||
if (!id) scope = enclosing(currscope)->sc_scope;
|
scope = enclosing(currscope)->sc_scope;
|
||||||
|
if (!id) imp_kind = FROM_ENCLOSING;
|
||||||
else {
|
else {
|
||||||
df = lookfor(id, 1);
|
imp_kind = FROM_MODULE;
|
||||||
|
df = lookfor(id, enclosing(currscope), 1);
|
||||||
if (df->df_kind != D_MODULE) {
|
if (df->df_kind != D_MODULE) {
|
||||||
|
/* enter all "ids" with type D_ERROR */
|
||||||
|
kind = D_ERROR;
|
||||||
if (df->df_kind != D_ERROR) {
|
if (df->df_kind != D_ERROR) {
|
||||||
error("identifier \"%s\" does not represent a module", id->id_text);
|
error("identifier \"%s\" does not represent a module", id->id_text);
|
||||||
}
|
}
|
||||||
/* enter all "ids" with type D_ERROR */
|
|
||||||
kind = D_ERROR;
|
|
||||||
scope = enclosing(currscope)->sc_scope;
|
|
||||||
}
|
}
|
||||||
else scope = df->mod_scope;
|
else scope = df->mod_scope;
|
||||||
}
|
}
|
||||||
while (ids) {
|
while (ids) {
|
||||||
df = lookup(ids->id_ptr, scope);
|
if (imp_kind == FROM_MODULE) {
|
||||||
if (!df) {
|
if (!(df = lookup(ids->id_ptr, scope))) {
|
||||||
error("identifier \"%s\" not declared",
|
error("identifier \"%s\" not declared in qualifying module",
|
||||||
ids->id_ptr->id_text);
|
ids->id_ptr->id_text);
|
||||||
|
df = ill_df;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
|
||||||
|
error("identifier \"%s\" not exported from qualifying module",
|
||||||
|
ids->id_ptr->id_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
df = lookfor(ids->id_ptr, enclosing(currscope), 0);
|
||||||
|
if (df->df_kind == D_ERROR) {
|
||||||
|
error("identifier \"%s\" not visible in enclosing scope",
|
||||||
|
ids->id_ptr->id_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
define(ids->id_ptr, CurrentScope, kind)->imp_def = df;
|
||||||
|
if (df->df_kind == D_TYPE &&
|
||||||
|
df->df_type->tp_fund == ENUMERATION) {
|
||||||
|
/* Also import all enumeration literals */
|
||||||
|
exprt_literals(df->df_type->enm_enums, currscope);
|
||||||
}
|
}
|
||||||
df = define(ids->id_ptr, CurrentScope, D_IMPORT);
|
|
||||||
df->imp_scopenr = scope;
|
|
||||||
ids = ids->next;
|
ids = ids->next;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* ???? */
|
/* ???? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exprt_literals(df, toscope)
|
||||||
|
register struct def *df;
|
||||||
|
register struct scope *toscope;
|
||||||
|
{
|
||||||
|
/* A list of enumeration literals is exported. This is implemented
|
||||||
|
as an import from the scope "toscope".
|
||||||
|
*/
|
||||||
|
while (df) {
|
||||||
|
define(df->df_idf, toscope->sc_scope, D_IMPORT)->imp_def = df;
|
||||||
|
df = df->enm_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -60,16 +60,18 @@ EnterIdList(idlist, kind, flags, type, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for an identifier in the current visibility range.
|
|
||||||
If it is not defined, give an error message, and
|
|
||||||
create a dummy definition.
|
|
||||||
*/
|
|
||||||
struct def *
|
struct def *
|
||||||
lookfor(id, give_error)
|
lookfor(id, scope, give_error)
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
struct scope *scope;
|
||||||
{
|
{
|
||||||
register struct scope *sc = currscope;
|
/* Look for an identifier in the visibility range started by
|
||||||
|
"scope".
|
||||||
|
If it is not defined, give an error message, and
|
||||||
|
create a dummy definition.
|
||||||
|
*/
|
||||||
struct def *df;
|
struct def *df;
|
||||||
|
register struct scope *sc = scope;
|
||||||
|
|
||||||
while (sc) {
|
while (sc) {
|
||||||
df = lookup(id, sc->sc_scope);
|
df = lookup(id, sc->sc_scope);
|
||||||
|
@ -77,5 +79,5 @@ lookfor(id, give_error)
|
||||||
sc = nextvisible(sc);
|
sc = nextvisible(sc);
|
||||||
}
|
}
|
||||||
if (give_error) error("Identifier \"%s\" not declared", id->id_text);
|
if (give_error) error("Identifier \"%s\" not declared", id->id_text);
|
||||||
return define(id, CurrentScope, D_ERROR);
|
return define(id, scope->sc_scope, D_ERROR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,12 @@ number:
|
||||||
qualident(int types; struct def **pdf; char *str;)
|
qualident(int types; struct def **pdf; char *str;)
|
||||||
{
|
{
|
||||||
int scope;
|
int scope;
|
||||||
|
int module;
|
||||||
register struct def *df;
|
register struct def *df;
|
||||||
struct def *lookfor();
|
struct def *lookfor();
|
||||||
} :
|
} :
|
||||||
IDENT { if (types) {
|
IDENT { if (types) {
|
||||||
*pdf = df = lookfor(dot.TOK_IDF, 1);
|
*pdf = df = lookfor(dot.TOK_IDF, currscope, 1);
|
||||||
if (df->df_kind == D_ERROR) types = 0;
|
if (df->df_kind == D_ERROR) types = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +39,7 @@ qualident(int types; struct def **pdf; char *str;)
|
||||||
/* selector */
|
/* selector */
|
||||||
'.' IDENT
|
'.' IDENT
|
||||||
{ if (types) {
|
{ if (types) {
|
||||||
|
module = (df->df_kind == D_MODULE);
|
||||||
df = lookup(dot.TOK_IDF, scope);
|
df = lookup(dot.TOK_IDF, scope);
|
||||||
if (!df) {
|
if (!df) {
|
||||||
error("identifier \"%s\" not declared",
|
error("identifier \"%s\" not declared",
|
||||||
|
@ -45,6 +47,11 @@ qualident(int types; struct def **pdf; char *str;)
|
||||||
types = 0;
|
types = 0;
|
||||||
df = ill_df;
|
df = ill_df;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (module &&
|
||||||
|
!(df->df_flags&(D_EXPORTED|D_QEXPORTED))) {
|
||||||
|
error("identifier \"%s\" not exported from qualifying module", dot.TOK_IDF->id_text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]*
|
]*
|
||||||
|
|
|
@ -35,9 +35,13 @@ static char *RcsId = "$Header$";
|
||||||
ModuleDeclaration
|
ModuleDeclaration
|
||||||
{
|
{
|
||||||
struct idf *id;
|
struct idf *id;
|
||||||
|
struct def *df;
|
||||||
} :
|
} :
|
||||||
MODULE IDENT { open_scope(CLOSEDSCOPE, 0);
|
MODULE IDENT {
|
||||||
id = dot.TOK_IDF;
|
id = dot.TOK_IDF;
|
||||||
|
df = define(id, CurrentScope, D_MODULE);
|
||||||
|
open_scope(CLOSEDSCOPE, 0);
|
||||||
|
df->mod_scope = CurrentScope;
|
||||||
}
|
}
|
||||||
priority? ';'
|
priority? ';'
|
||||||
import(1)*
|
import(1)*
|
||||||
|
|
|
@ -118,7 +118,7 @@ rem_forwards(fo)
|
||||||
savetok = dot;
|
savetok = dot;
|
||||||
while (f = fo) {
|
while (f = fo) {
|
||||||
dot = f->fo_tok;
|
dot = f->fo_tok;
|
||||||
df = lookfor(dot.TOK_IDF, 1);
|
df = lookfor(dot.TOK_IDF, currscope, 1);
|
||||||
if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
|
if (!(df->df_kind & (D_TYPE | D_HTYPE | D_ERROR))) {
|
||||||
error("identifier \"%s\" not a type", df->df_idf->id_text);
|
error("identifier \"%s\" not a type", df->df_idf->id_text);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue