then stores a name for that entry. C<name> is adopted and
becomes the name entry; it must already contain the name
string. C<typestash> and C<ourstash> and the C<padadd_STATE>
-flag get added to C<name>. None of the other
-processing of L<perlapi/pad_add_name_pvn>
+and C<padadd_TOMBSTONE> flags get added to C<name>.
+None of the other processing of L<perlapi/pad_add_name_pvn>
is done. Returns the offset of the allocated pad slot.
=cut
assert(HvSTASH_IS_CLASS(PL_curstash));
class_add_field(PL_curstash, name);
}
+ if (flags & padadd_TOMBSTONE) {
+ PadnameFLAGS(name) |= PADNAMEf_TOMBSTONE;
+ }
padnamelist_store(PL_comppad_name, offset, name);
if (PadnameLEN(name) > 1)
padadd_STATE variable will retain value persistently
padadd_NO_DUP_CHECK skip check for lexical shadowing
padadd_FIELD specifies that the lexical is a field for a class
+ padadd_TOMBSTONE sets the PadnameIsTOMBSTONE flag on the new name
=cut
*/
PERL_ARGS_ASSERT_PAD_ADD_NAME_PVN;
- if (flags & ~(padadd_OUR|padadd_STATE|padadd_NO_DUP_CHECK|padadd_FIELD))
+ if (flags & ~(padadd_OUR|padadd_STATE|padadd_NO_DUP_CHECK|padadd_FIELD|padadd_TOMBSTONE))
Perl_croak(aTHX_ "panic: pad_add_name_pvn illegal flag bits 0x%" UVxf,
(UV)flags);
name = newPADNAMEpvn(namepv, namelen);
- if ((flags & padadd_NO_DUP_CHECK) == 0) {
+ if ((flags & (padadd_NO_DUP_CHECK|padadd_TOMBSTONE)) == 0) {
ENTER;
SAVEFREEPADNAME(name); /* in case of fatal warnings */
/* check for duplicate declaration */
if (pn
&& PadnameLEN(pn) == PadnameLEN(name)
&& !PadnameOUTER(pn)
+ && !PadnameIsTOMBSTONE(pn)
&& ( COP_SEQ_RANGE_LOW(pn) == PERL_PADSEQ_INTRO
|| COP_SEQ_RANGE_HIGH(pn) == PERL_PADSEQ_INTRO)
&& memEQ(PadnamePV(pn), PadnamePV(name), PadnameLEN(name)))
fake_offset = 0;
*out_name = name_p[offset]; /* return the name */
+ if (PadnameIsTOMBSTONE(*out_name))
+ /* is this a lexical import that has been deleted? */
+ return NOT_IN_PAD;
+
if (PadnameIsFIELD(*out_name) && !fieldok)
croak("Field %" SVf " is not accessible outside a method",
SVfARG(PadnameSV(*out_name)));
* sub, but only one level up */
#define padadd_FIELD 0x10 /* set PADNAMEt_FIELD */
#define padfind_FIELD_OK 0x20 /* pad_findlex is permitted to see fields */
+#define padadd_TOMBSTONE 0x40 /* set PadnameIsTOMBSTONE on the new entry */
/* ASSERT_CURPAD_LEGAL and ASSERT_CURPAD_ACTIVE respectively determine
* whether PL_comppad and PL_curpad are consistent and whether they have
Whether this is a "field" variable. PADNAMEs where this is true will
have additional information available via C<PadnameFIELDINFO>.
+=for apidoc m|bool|PadnameIsTOMBSTONE|PADNAME * pn
+Whether this pad entry is a tombstone. Such an entry indicates that a
+previously-valid pad entry has now been deleted within this scope, and
+should be ignored.
+
=for apidoc m|HV *|PadnameTYPE|PADNAME * pn
The stash associated with a typed lexical. This returns the C<%Foo::> hash
for C<my Foo $bar>.
#define PadnameIsSTATE(pn) (PadnameFLAGS(pn) & PADNAMEf_STATE)
#define PadnameLVALUE(pn) (PadnameFLAGS(pn) & PADNAMEf_LVALUE)
#define PadnameIsFIELD(pn) (PadnameFLAGS(pn) & PADNAMEf_FIELD)
-
-#define PadnameLVALUE_on(pn) (PadnameFLAGS(pn) |= PADNAMEf_LVALUE)
-#define PadnameIsSTATE_on(pn) (PadnameFLAGS(pn) |= PADNAMEf_STATE)
-
-#define PADNAMEf_OUTER 0x01 /* outer lexical var */
-#define PADNAMEf_STATE 0x02 /* state var */
-#define PADNAMEf_LVALUE 0x04 /* used as lvalue */
-#define PADNAMEf_TYPED 0x08 /* for B; unused by core */
-#define PADNAMEf_OUR 0x10 /* for B; unused by core */
-#define PADNAMEf_FIELD 0x20 /* field var */
+#define PadnameIsTOMBSTONE(pn) (PadnameFLAGS(pn) & PADNAMEf_TOMBSTONE)
+
+#define PadnameLVALUE_on(pn) (PadnameFLAGS(pn) |= PADNAMEf_LVALUE)
+#define PadnameIsSTATE_on(pn) (PadnameFLAGS(pn) |= PADNAMEf_STATE)
+
+#define PADNAMEf_OUTER 0x01 /* outer lexical var */
+#define PADNAMEf_STATE 0x02 /* state var */
+#define PADNAMEf_LVALUE 0x04 /* used as lvalue */
+#define PADNAMEf_TYPED 0x08 /* for B; unused by core */
+#define PADNAMEf_OUR 0x10 /* for B; unused by core */
+#define PADNAMEf_FIELD 0x20 /* field var */
+#define PADNAMEf_TOMBSTONE 0x40 /* padname has been deleted */
/* backward compatibility */
#ifndef PERL_CORE