mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 01:39:26 +02:00
Allow generics to be overloaded by variables.
* symconst.pas: add an entry for the generic dummy symbol to the symbol options enumeration * pgenutil.pas: - extend "generate_specialization" by the possibility to pass a symbol name instead of a def - if "symname" is given that is used; otherwise "genericdef" or "tt" is used * pexpr.pas: - in case of "<" we are trying to receive a generic dummy symbol from the left node (new function "getgenericsym") - it's name is then passed to "generate_specialization" which in turn fills genericdef - adjust call to "generate_specialization" * pdecl.pas: - we can now check for "sp_generic_dummy instead of "not sp_generic_para" to check whether we've found the dummy symbol of a previous generic declaration - if a new dummy symbol is created we need to include "sp_generic_dummy" - if we've found a non-generic symbol with the same name we need to include the "sp_generic_dummy" flag as well * symtable.pas - add a new function "searchsym_with_symoption" that more or less works the same as "searchsym", but only returns successfully if the found symbol contains the given flag - "searchsym_with_symoption" and "searchsym" are based on the same function "maybe_searchsym_with_symoption" which is the extended implementation of "searchsym" (note: object symtables are not yet searched if a symoption is to be looked for) - add a function "handle_generic_dummysym" which can be used to hide the undefineddef symbol in a symtable - correctly handle generic dummy symbols in case of variables in "tstaticsymtable.checkduplicate" git-svn-id: branches/svenbarth/generics@19429 -
This commit is contained in:
parent
a93aeebb1f
commit
90278ec755
@ -439,7 +439,7 @@ implementation
|
|||||||
that was declared earlier }
|
that was declared earlier }
|
||||||
not (
|
not (
|
||||||
(ttypesym(sym).typedef.typ=undefineddef) and
|
(ttypesym(sym).typedef.typ=undefineddef) and
|
||||||
not (sp_generic_para in sym.symoptions)
|
(sp_generic_dummy in sym.symoptions)
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
if ((token=_CLASS) or
|
if ((token=_CLASS) or
|
||||||
@ -499,6 +499,7 @@ implementation
|
|||||||
if not assigned(sym) then
|
if not assigned(sym) then
|
||||||
begin
|
begin
|
||||||
sym:=ttypesym.create(orgtypename,tundefineddef.create);
|
sym:=ttypesym.create(orgtypename,tundefineddef.create);
|
||||||
|
Include(sym.symoptions,sp_generic_dummy);
|
||||||
ttypesym(sym).typedef.typesym:=sym;
|
ttypesym(sym).typedef.typesym:=sym;
|
||||||
sym.visibility:=symtablestack.top.currentvisibility;
|
sym.visibility:=symtablestack.top.currentvisibility;
|
||||||
symtablestack.top.insert(sym);
|
symtablestack.top.insert(sym);
|
||||||
@ -507,13 +508,17 @@ implementation
|
|||||||
else
|
else
|
||||||
{ this is not allowed in non-Delphi modes }
|
{ this is not allowed in non-Delphi modes }
|
||||||
if not (m_delphi in current_settings.modeswitches) then
|
if not (m_delphi in current_settings.modeswitches) then
|
||||||
Message1(sym_e_duplicate_id,genorgtypename);
|
Message1(sym_e_duplicate_id,genorgtypename)
|
||||||
|
else
|
||||||
|
{ we need to find this symbol even if it's a variable or
|
||||||
|
something else when doing an inline specialization }
|
||||||
|
Include(sym.symoptions,sp_generic_dummy);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if assigned(sym) and (sym.typ=typesym) and
|
if assigned(sym) and (sym.typ=typesym) and
|
||||||
(ttypesym(sym).typedef.typ=undefineddef) and
|
(ttypesym(sym).typedef.typ=undefineddef) and
|
||||||
not (sp_generic_para in sym.symoptions) then
|
(sp_generic_dummy in sym.symoptions) then
|
||||||
begin
|
begin
|
||||||
{ this is a symbol that was added by an earlier generic
|
{ this is a symbol that was added by an earlier generic
|
||||||
declaration, reuse it }
|
declaration, reuse it }
|
||||||
|
@ -2896,12 +2896,31 @@ implementation
|
|||||||
result:=ttypenode(tloadvmtaddrnode(n).left).typedef;
|
result:=ttypenode(tloadvmtaddrnode(n).left).typedef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function getgenericsym(n:tnode;out srsym:tsym):boolean;
|
||||||
|
var
|
||||||
|
srsymtable : tsymtable;
|
||||||
|
begin
|
||||||
|
srsym:=nil;
|
||||||
|
case n.nodetype of
|
||||||
|
typen:
|
||||||
|
srsym:=ttypenode(n).typedef.typesym;
|
||||||
|
loadvmtaddrn:
|
||||||
|
srsym:=ttypenode(tloadvmtaddrnode(n).left).typedef.typesym;
|
||||||
|
loadn:
|
||||||
|
if not searchsym_with_symoption(tloadnode(n).symtableentry.Name,srsym,srsymtable,sp_generic_dummy) then
|
||||||
|
srsym:=nil;
|
||||||
|
{ TODO : handle const nodes }
|
||||||
|
end;
|
||||||
|
result:=assigned(srsym);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
p1,p2 : tnode;
|
p1,p2 : tnode;
|
||||||
oldt : Ttoken;
|
oldt : Ttoken;
|
||||||
filepos : tfileposinfo;
|
filepos : tfileposinfo;
|
||||||
again : boolean;
|
again : boolean;
|
||||||
gendef,parseddef : tdef;
|
gendef,parseddef : tdef;
|
||||||
|
gensym : tsym;
|
||||||
begin
|
begin
|
||||||
if pred_level=highest_precedence then
|
if pred_level=highest_precedence then
|
||||||
p1:=factor(false,typeonly)
|
p1:=factor(false,typeonly)
|
||||||
@ -2941,18 +2960,20 @@ implementation
|
|||||||
same name is defined in the same unit where the
|
same name is defined in the same unit where the
|
||||||
generic is defined (though "same unit" is not
|
generic is defined (though "same unit" is not
|
||||||
necessarily needed) }
|
necessarily needed) }
|
||||||
if istypenode(p1) and istypenode(p2) and
|
if getgenericsym(p1,gensym) and
|
||||||
|
{ Attention: when nested specializations are supported
|
||||||
|
p2 could be a loadn if a "<" follows }
|
||||||
|
istypenode(p2) and
|
||||||
(m_delphi in current_settings.modeswitches) and
|
(m_delphi in current_settings.modeswitches) and
|
||||||
|
{ TODO : add _LT, _LSHARPBRACKET for nested specializations }
|
||||||
(token in [_GT,_RSHARPBRACKET,_COMMA]) then
|
(token in [_GT,_RSHARPBRACKET,_COMMA]) then
|
||||||
begin
|
begin
|
||||||
{ this is an inline specialization }
|
{ this is an inline specialization }
|
||||||
|
|
||||||
{ retrieve the defs of two nodes }
|
{ retrieve the defs of two nodes }
|
||||||
gendef:=gettypedef(p1);
|
gendef:=nil;
|
||||||
parseddef:=gettypedef(p2);
|
parseddef:=gettypedef(p2);
|
||||||
|
|
||||||
if gendef.typesym.typ<>typesym then
|
|
||||||
Internalerror(2011050301);
|
|
||||||
if parseddef.typesym.typ<>typesym then
|
if parseddef.typesym.typ<>typesym then
|
||||||
Internalerror(2011051001);
|
Internalerror(2011051001);
|
||||||
|
|
||||||
@ -2960,7 +2981,7 @@ implementation
|
|||||||
check_hints(parseddef.typesym,parseddef.typesym.symoptions,parseddef.typesym.deprecatedmsg);
|
check_hints(parseddef.typesym,parseddef.typesym.symoptions,parseddef.typesym.deprecatedmsg);
|
||||||
|
|
||||||
{ generate the specialization }
|
{ generate the specialization }
|
||||||
generate_specialization(gendef,false,parseddef);
|
generate_specialization(gendef,false,parseddef,gensym.RealName);
|
||||||
|
|
||||||
{ we don't need the old left and right nodes anymore }
|
{ we don't need the old left and right nodes anymore }
|
||||||
p1.Free;
|
p1.Free;
|
||||||
@ -3041,7 +3062,7 @@ implementation
|
|||||||
Internalerror(2011071401);
|
Internalerror(2011071401);
|
||||||
|
|
||||||
{ generate the specialization }
|
{ generate the specialization }
|
||||||
generate_specialization(gendef,false,nil);
|
generate_specialization(gendef,false,nil,'');
|
||||||
|
|
||||||
{ we don't need the old p2 anymore }
|
{ we don't need the old p2 anymore }
|
||||||
p2.Free;
|
p2.Free;
|
||||||
|
@ -32,7 +32,7 @@ uses
|
|||||||
{ symtable }
|
{ symtable }
|
||||||
symtype,symdef;
|
symtype,symdef;
|
||||||
|
|
||||||
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;parsedtype:tdef);
|
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;parsedtype:tdef;symname:string);
|
||||||
function parse_generic_parameters:TFPObjectList;
|
function parse_generic_parameters:TFPObjectList;
|
||||||
procedure insert_generic_parameter_types(def:tstoreddef;genericdef:tstoreddef;genericlist:TFPObjectList);
|
procedure insert_generic_parameter_types(def:tstoreddef;genericdef:tstoreddef;genericlist:TFPObjectList);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ uses
|
|||||||
pbase,pexpr,pdecsub,ptype;
|
pbase,pexpr,pdecsub,ptype;
|
||||||
|
|
||||||
|
|
||||||
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;parsedtype:tdef);
|
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;parsedtype:tdef;symname:string);
|
||||||
var
|
var
|
||||||
st : TSymtable;
|
st : TSymtable;
|
||||||
srsym : tsym;
|
srsym : tsym;
|
||||||
@ -65,7 +65,6 @@ uses
|
|||||||
i,
|
i,
|
||||||
gencount : longint;
|
gencount : longint;
|
||||||
genericdef : tstoreddef;
|
genericdef : tstoreddef;
|
||||||
genericsym,
|
|
||||||
generictype : ttypesym;
|
generictype : ttypesym;
|
||||||
genericdeflist : TFPObjectList;
|
genericdeflist : TFPObjectList;
|
||||||
generictypelist : TFPObjectList;
|
generictypelist : TFPObjectList;
|
||||||
@ -85,12 +84,13 @@ uses
|
|||||||
tt:=nil;
|
tt:=nil;
|
||||||
onlyparsepara:=false;
|
onlyparsepara:=false;
|
||||||
|
|
||||||
if not assigned(genericdef.typesym) or
|
{ either symname must be given or genericdef needs to be valid }
|
||||||
(genericdef.typesym.typ<>typesym) then
|
if (symname='') and
|
||||||
|
(not assigned(genericdef) or
|
||||||
|
not assigned(genericdef.typesym) or
|
||||||
|
(genericdef.typesym.typ<>typesym)) then
|
||||||
internalerror(2011042701);
|
internalerror(2011042701);
|
||||||
|
|
||||||
genericsym:=ttypesym(genericdef.typesym);
|
|
||||||
|
|
||||||
{ only need to record the tokens, then we don't know the type yet ... }
|
{ only need to record the tokens, then we don't know the type yet ... }
|
||||||
if parse_generic then
|
if parse_generic then
|
||||||
begin
|
begin
|
||||||
@ -117,7 +117,7 @@ uses
|
|||||||
consume(_RSHARPBRACKET);
|
consume(_RSHARPBRACKET);
|
||||||
if parse_generic and parse_class_parent then
|
if parse_generic and parse_class_parent then
|
||||||
begin
|
begin
|
||||||
if df_generic in genericdef.defoptions then
|
if (symname='') and (df_generic in genericdef.defoptions) then
|
||||||
{ this happens in non-Delphi modes }
|
{ this happens in non-Delphi modes }
|
||||||
tt:=genericdef
|
tt:=genericdef
|
||||||
else
|
else
|
||||||
@ -125,7 +125,11 @@ uses
|
|||||||
{ find the corresponding generic symbol so that any checks
|
{ find the corresponding generic symbol so that any checks
|
||||||
done on the returned def will be handled correctly }
|
done on the returned def will be handled correctly }
|
||||||
str(gencount,countstr);
|
str(gencount,countstr);
|
||||||
genname:=ttypesym(genericdef.typesym).realname+'$'+countstr;
|
if symname='' then
|
||||||
|
genname:=ttypesym(genericdef.typesym).realname
|
||||||
|
else
|
||||||
|
genname:=symname;
|
||||||
|
genname:=symname+'$'+countstr;
|
||||||
ugenname:=upper(genname);
|
ugenname:=upper(genname);
|
||||||
if not searchsym(ugenname,srsym,st) or
|
if not searchsym(ugenname,srsym,st) or
|
||||||
(srsym.typ<>typesym) then
|
(srsym.typ<>typesym) then
|
||||||
@ -146,8 +150,6 @@ uses
|
|||||||
genericdeflist:=TFPObjectList.Create(false);
|
genericdeflist:=TFPObjectList.Create(false);
|
||||||
|
|
||||||
{ Parse type parameters }
|
{ Parse type parameters }
|
||||||
if not assigned(genericdef.typesym) then
|
|
||||||
internalerror(200710173);
|
|
||||||
err:=false;
|
err:=false;
|
||||||
{ if parsedtype is set, then the first type identifer was already parsed
|
{ if parsedtype is set, then the first type identifer was already parsed
|
||||||
(happens in inline specializations) and thus we only need to parse
|
(happens in inline specializations) and thus we only need to parse
|
||||||
@ -196,10 +198,13 @@ uses
|
|||||||
str(genericdeflist.Count,countstr);
|
str(genericdeflist.Count,countstr);
|
||||||
{ use the name of the symbol as procvars return a user friendly version
|
{ use the name of the symbol as procvars return a user friendly version
|
||||||
of the name }
|
of the name }
|
||||||
genname:=ttypesym(genericdef.typesym).realname;
|
if symname='' then
|
||||||
|
genname:=ttypesym(genericdef.typesym).realname
|
||||||
|
else
|
||||||
|
genname:=symname;
|
||||||
{ in case of non-Delphi mode the type name could already be a generic
|
{ in case of non-Delphi mode the type name could already be a generic
|
||||||
def (but maybe the wrong one) }
|
def (but maybe the wrong one) }
|
||||||
if df_generic in genericdef.defoptions then
|
if assigned(genericdef) and (df_generic in genericdef.defoptions) then
|
||||||
begin
|
begin
|
||||||
{ remove the type count suffix from the generic's name }
|
{ remove the type count suffix from the generic's name }
|
||||||
for i:=Length(genname) downto 1 do
|
for i:=Length(genname) downto 1 do
|
||||||
|
@ -370,7 +370,7 @@ implementation
|
|||||||
(m_delphi in current_settings.modeswitches) then
|
(m_delphi in current_settings.modeswitches) then
|
||||||
dospecialize:=token=_LSHARPBRACKET;
|
dospecialize:=token=_LSHARPBRACKET;
|
||||||
if dospecialize then
|
if dospecialize then
|
||||||
generate_specialization(def,stoParseClassParent in options,nil)
|
generate_specialization(def,stoParseClassParent in options,nil,'')
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if assigned(current_specializedef) and (def=current_specializedef.genericdef) then
|
if assigned(current_specializedef) and (def=current_specializedef.genericdef) then
|
||||||
@ -839,7 +839,7 @@ implementation
|
|||||||
dospecialize:=token=_LSHARPBRACKET;
|
dospecialize:=token=_LSHARPBRACKET;
|
||||||
if dospecialize then
|
if dospecialize then
|
||||||
begin
|
begin
|
||||||
generate_specialization(def,false,nil);
|
generate_specialization(def,false,nil,'');
|
||||||
{ handle nested types }
|
{ handle nested types }
|
||||||
post_comp_expr_gendef(def);
|
post_comp_expr_gendef(def);
|
||||||
end
|
end
|
||||||
|
@ -167,7 +167,11 @@ type
|
|||||||
sp_implicitrename,
|
sp_implicitrename,
|
||||||
sp_hint_experimental,
|
sp_hint_experimental,
|
||||||
sp_generic_para,
|
sp_generic_para,
|
||||||
sp_has_deprecated_msg
|
sp_has_deprecated_msg,
|
||||||
|
sp_generic_dummy { this is used for symbols that are generated when a
|
||||||
|
generic is encountered to ease inline
|
||||||
|
specializations, etc; those symbols can be
|
||||||
|
"overridden" with a completely different symbol }
|
||||||
);
|
);
|
||||||
tsymoptions=set of tsymoption;
|
tsymoptions=set of tsymoption;
|
||||||
|
|
||||||
|
@ -209,6 +209,7 @@ interface
|
|||||||
procedure incompatibletypes(def1,def2:tdef);
|
procedure incompatibletypes(def1,def2:tdef);
|
||||||
procedure hidesym(sym:TSymEntry);
|
procedure hidesym(sym:TSymEntry);
|
||||||
procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
|
procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
|
||||||
|
function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean;
|
||||||
|
|
||||||
{*** Search ***}
|
{*** Search ***}
|
||||||
procedure addsymref(sym:tsym);
|
procedure addsymref(sym:tsym);
|
||||||
@ -217,6 +218,10 @@ interface
|
|||||||
function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
|
function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
|
||||||
function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
|
function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
|
||||||
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
|
function searchsym_maybe_with_symoption(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable;searchoption:boolean;option:tsymoption):boolean;
|
||||||
|
{ searches for a symbol with the given name that has the given option in
|
||||||
|
symoptions set }
|
||||||
|
function searchsym_with_symoption(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable;option:tsymoption):boolean;
|
||||||
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
|
function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
|
||||||
@ -1479,6 +1484,8 @@ implementation
|
|||||||
hsym:=tsym(FindWithHash(hashedid));
|
hsym:=tsym(FindWithHash(hashedid));
|
||||||
if assigned(hsym) then
|
if assigned(hsym) then
|
||||||
begin
|
begin
|
||||||
|
if (sym is tstoredsym) and handle_generic_dummysym(hsym,tstoredsym(sym).symoptions) then
|
||||||
|
exit;
|
||||||
{ Delphi (contrary to TP) you can have a symbol with the same name as the
|
{ Delphi (contrary to TP) you can have a symbol with the same name as the
|
||||||
unit, the unit can then not be accessed anymore using
|
unit, the unit can then not be accessed anymore using
|
||||||
<unit>.<id>, so we can hide the symbol }
|
<unit>.<id>, so we can hide the symbol }
|
||||||
@ -1755,6 +1762,29 @@ implementation
|
|||||||
include(tsym(dupsym).symoptions,sp_implicitrename);
|
include(tsym(dupsym).symoptions,sp_implicitrename);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function handle_generic_dummysym(sym:TSymEntry;var symoptions:tsymoptions):boolean;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
if not assigned(sym) or not (sym is tstoredsym) then
|
||||||
|
Internalerror(2011081101);
|
||||||
|
{ For generics a dummy symbol without the parameter count is created
|
||||||
|
if such a symbol not yet exists so that different parts of the
|
||||||
|
parser can find that symbol. If that symbol is still a
|
||||||
|
undefineddef we replace the generic dummy symbol's
|
||||||
|
name with a "dup" name and use the new symbol as the generic dummy
|
||||||
|
symbol }
|
||||||
|
if (sp_generic_dummy in tstoredsym(sym).symoptions) and
|
||||||
|
(sym.typ=typesym) and (ttypesym(sym).typedef.typ=undefineddef) and
|
||||||
|
(m_delphi in current_settings.modeswitches) then
|
||||||
|
begin
|
||||||
|
inc(dupnr);
|
||||||
|
sym.Owner.SymList.Rename(upper(sym.realname),'dup_'+tostr(dupnr)+sym.realname);
|
||||||
|
include(tsym(sym).symoptions,sp_implicitrename);
|
||||||
|
{ we need to find the new symbol now if checking for a dummy }
|
||||||
|
include(symoptions,sp_generic_dummy);
|
||||||
|
result:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
Search
|
Search
|
||||||
@ -1911,6 +1941,11 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
|
begin
|
||||||
|
result:=searchsym_maybe_with_symoption(s,srsym,srsymtable,false,sp_none);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function searchsym_maybe_with_symoption(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable;searchoption:boolean;option:tsymoption):boolean;
|
||||||
var
|
var
|
||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
contextstructdef : tabstractrecorddef;
|
contextstructdef : tabstractrecorddef;
|
||||||
@ -1924,6 +1959,12 @@ implementation
|
|||||||
srsymtable:=stackitem^.symtable;
|
srsymtable:=stackitem^.symtable;
|
||||||
if (srsymtable.symtabletype=objectsymtable) then
|
if (srsymtable.symtabletype=objectsymtable) then
|
||||||
begin
|
begin
|
||||||
|
{ TODO : implement the search for an option in classes as well }
|
||||||
|
if searchoption then
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
if searchsym_in_class(tobjectdef(srsymtable.defowner),tobjectdef(srsymtable.defowner),s,srsym,srsymtable,true) then
|
if searchsym_in_class(tobjectdef(srsymtable.defowner),tobjectdef(srsymtable.defowner),s,srsym,srsymtable,true) then
|
||||||
begin
|
begin
|
||||||
result:=true;
|
result:=true;
|
||||||
@ -1946,7 +1987,8 @@ implementation
|
|||||||
else
|
else
|
||||||
contextstructdef:=current_structdef;
|
contextstructdef:=current_structdef;
|
||||||
if not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
|
if not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
|
||||||
is_visible_for_object(srsym,contextstructdef) then
|
is_visible_for_object(srsym,contextstructdef) and
|
||||||
|
(not searchoption or (option in srsym.symoptions)) then
|
||||||
begin
|
begin
|
||||||
{ we need to know if a procedure references symbols
|
{ we need to know if a procedure references symbols
|
||||||
in the static symtable, because then it can't be
|
in the static symtable, because then it can't be
|
||||||
@ -1966,6 +2008,11 @@ implementation
|
|||||||
srsymtable:=nil;
|
srsymtable:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function searchsym_with_symoption(const s: TIDString;out srsym:tsym;out
|
||||||
|
srsymtable:TSymtable;option:tsymoption):boolean;
|
||||||
|
begin
|
||||||
|
result:=searchsym_maybe_with_symoption(s,srsym,srsymtable,true,option);
|
||||||
|
end;
|
||||||
|
|
||||||
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
var
|
var
|
||||||
|
Loading…
Reference in New Issue
Block a user