/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)yyid.c 1.4 8/26/82";
* Determine whether the identifier whose name
* is "cp" can possibly be a kind, which is a
* namelist class. We look through the symbol
* table for the first instance of cp as a non-field,
* and at all instances of cp as a field.
* If any of these are ok, we return true, else false.
* It would be much better to handle with's correctly,
* even to just know whether we are in a with at all.
* Note that we don't disallow constants on the lhs of assignment.
* Cp is NIL when error recovery inserts it.
* Record kind we want for possible later use by yyrecover
for (p
= disptab
[i
]; p
!= NIL
; p
= p
->nl_next
)
if (p
->class != FIELD
&& p
->class != BADUSE
)
for (p
= p
->nl_next
; p
!= NIL
; p
= p
->nl_next
)
if (p
->symbol
== cp
&& p
->class == FIELD
&& yyidok(p
, kind
))
if (p
->class == BADUSE
&& !Recovery
) {
* A bad reference to the identifier cp on line
* line and use implying the addition of kindmask
* to the mask of kind information.
yybaduse(cp
, line
, kindmask
)
register struct nl
*p
, *oldp
;
for (p
= disptab
[i
]; p
!= NIL
; p
= p
->nl_next
)
if (p
== NIL
|| p
->class != BADUSE
)
p
= enter(defnl(cp
, BADUSE
, 0, 0));
p
->value
[NL_KINDS
] |= kindmask
;
* ud is initialized so that esavestr will allocate
* sizeof ( struct udinfo ) bytes for the 'real' struct udinfo
struct udinfo ud
= { ~0 , ~0 , 0};
* Record a reference to an undefined identifier,
* or one which is improperly used.
register struct udinfo
*udp
;
if (p
->chain
!= NIL
&& p
->chain
->ud_line
== line
)
#define varkinds ((1<<CONST)|(1<<VAR)|(1<<REF)|(1<<ARRAY)|(1<<PTR) \
|(1<<RECORD)|(1<<FIELD)|(1<<FUNC)|(1<<FVAR) \
|(1<<FFUNC)|(1<<PROC)|(1<<FPROC))
* Is the symbol in the p entry of the namelist
* even possibly a kind kind? If not, update
* what we have based on this encounter.
if (p
->class == BADUSE
) {
return (p
->value
[0] & varkinds
);
return (p
->value
[0] & (1 << kind
));
return ( p
-> class == FUNC
|| p
-> class == FFUNC
);
return ( p
-> class == PROC
|| p
-> class == FPROC
);
return (p
->class == kind
);
return (p
->class == CONST
|| yyisvar(p
, NIL
));
return (yyisvar(p
, kind
));
return (yyisvar(p
, PTR
) || yyisvar(p
, FILET
));
* We would prefer to return
* parameterless functions only.
return (varclass
== NIL
|| (p
->type
!= NIL
&& p
->type
->class == varclass
));
return ( varclass
== NIL
);
char kindchars
[] "UCTVAQRDPF";
* Fake routine "identis" for pxp when testing error recovery.
* Looks at letters in variable names to answer questions
* about attributes. Mapping is
* V var_id also if any of AQRDF
* Don't do anything unless -T
* Inserted symbols are always correct
* Set up the names for error messages
yyidwant
= classes
[kind
];
for (dp
= kindchars
; *dp
; dp
++)
yyidhave
= classes
[dp
- kindchars
];
* U in the name means undefined
kindch
= kindchars
[kind
];
for (dp
= "AQRDF"; *dp
; dp
++)
return (any(cp
, kindch
));