mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 06:51:46 +02:00
Corrected the handling of hint directives.
pgenutils.pas/generate_specialization: - parse hint directives of the generic if they are recorded - output hint messages of the generic after the ">" is successfully parsed pexpr.pas: - factor: don't display hints of a potential generic type if the next token is a "<" - sub_expr: * added two inline methods which a) checks whether a node is a typenode or a loadvmtaddrnode with a typenode b) returns the typedef of such a node * check hint directives for the first parsed type argument of a specialization * in the case of parsing a non-generic type the hints of the left and right node of the resulting "<" node need to be checked (the right ones only if another "<" is following) git-svn-id: branches/svenbarth/generics@17539 -
This commit is contained in:
parent
c17a8d36ae
commit
6c96270eb6
@ -1913,14 +1913,12 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ check hints if it is the final symbol that is used (e.g. in
|
{ check hints, but only if it isn't a potential generic symbol;
|
||||||
case of generics only the dummy symbol or the non-generic one
|
that is checked in sub_expr if it isn't a generic }
|
||||||
is found here }
|
|
||||||
{ TODO : correct this check }
|
|
||||||
if assigned(srsym) and
|
if assigned(srsym) and
|
||||||
not (
|
not (
|
||||||
typeonly and (srsym.typ=typesym) and
|
(srsym.typ=typesym) and
|
||||||
(ttypesym(srsym).typedef.typ=undefineddef) and
|
(ttypesym(srsym).typedef.typ in [recorddef,objectdef,arraydef,procvardef,undefineddef]) and
|
||||||
not (sp_generic_para in srsym.symoptions) and
|
not (sp_generic_para in srsym.symoptions) and
|
||||||
(token in [_LT, _LSHARPBRACKET])
|
(token in [_LT, _LSHARPBRACKET])
|
||||||
) then
|
) then
|
||||||
@ -2838,6 +2836,32 @@ implementation
|
|||||||
{Reads a subexpression while the operators are of the current precedence
|
{Reads a subexpression while the operators are of the current precedence
|
||||||
level, or any higher level. Replaces the old term, simpl_expr and
|
level, or any higher level. Replaces the old term, simpl_expr and
|
||||||
simpl2_expr.}
|
simpl2_expr.}
|
||||||
|
|
||||||
|
function istypenode(n:tnode):boolean;inline;
|
||||||
|
{ Checks whether the given node is a type node or a VMT node containing a
|
||||||
|
typenode. This is used in the code for inline specializations in the
|
||||||
|
_LT branch below }
|
||||||
|
begin
|
||||||
|
result:=assigned(n) and
|
||||||
|
(
|
||||||
|
(n.nodetype=typen) or
|
||||||
|
(
|
||||||
|
(n.nodetype=loadvmtaddrn) and
|
||||||
|
(tloadvmtaddrnode(n).left.nodetype=typen)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function gettypedef(n:tnode):tdef;inline;
|
||||||
|
{ This returns the typedef that belongs to the given typenode or
|
||||||
|
loadvmtaddrnode. n must not be Nil! }
|
||||||
|
begin
|
||||||
|
if n.nodetype=typen then
|
||||||
|
result:=ttypenode(n).typedef
|
||||||
|
else
|
||||||
|
result:=ttypenode(tloadvmtaddrnode(n).left).typedef;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
p1,p2 : tnode;
|
p1,p2 : tnode;
|
||||||
oldt : Ttoken;
|
oldt : Ttoken;
|
||||||
@ -2878,57 +2902,57 @@ implementation
|
|||||||
_LT :
|
_LT :
|
||||||
begin
|
begin
|
||||||
isgeneric:=false;
|
isgeneric:=false;
|
||||||
if (
|
if istypenode(p1) and istypenode(p2) and
|
||||||
{ the left node needs to be a type node }
|
|
||||||
(p1.nodetype=typen) or
|
|
||||||
(
|
|
||||||
(p1.nodetype=loadvmtaddrn) and
|
|
||||||
(tloadvmtaddrnode(p1).left.nodetype=typen)
|
|
||||||
)
|
|
||||||
) and
|
|
||||||
(
|
|
||||||
{ the right node needs to be a type node }
|
|
||||||
(p2.nodetype=typen) or
|
|
||||||
(
|
|
||||||
(p2.nodetype=loadvmtaddrn) and
|
|
||||||
(tloadvmtaddrnode(p2).left.nodetype=typen)
|
|
||||||
)
|
|
||||||
) and
|
|
||||||
(m_delphi in current_settings.modeswitches) and
|
(m_delphi in current_settings.modeswitches) and
|
||||||
(token in [_GT,_RSHARPBRACKET,_COMMA]) then
|
(token in [_GT,_RSHARPBRACKET,_COMMA]) then
|
||||||
begin
|
begin
|
||||||
{ this is an inline specialization }
|
{ this is an inline specialization }
|
||||||
|
|
||||||
{ retrive the def of the left node }
|
{ retrieve the defs of two nodes }
|
||||||
if p1.nodetype=typen then
|
gendef:=gettypedef(p1);
|
||||||
gendef:=ttypenode(p1).typedef
|
parseddef:=gettypedef(p2);
|
||||||
else
|
|
||||||
gendef:=ttypenode(tloadvmtaddrnode(p1).left).typedef;
|
|
||||||
|
|
||||||
{ retrieve the right node }
|
|
||||||
if p2.nodetype=typen then
|
|
||||||
parseddef:=ttypenode(p2).typedef
|
|
||||||
else
|
|
||||||
parseddef:=ttypenode(tloadvmtaddrnode(p2).left).typedef;
|
|
||||||
|
|
||||||
if gendef.typesym.typ<>typesym then
|
if gendef.typesym.typ<>typesym then
|
||||||
Internalerror(2011050301);
|
Internalerror(2011050301);
|
||||||
if parseddef.typesym.typ<>typesym then
|
if parseddef.typesym.typ<>typesym then
|
||||||
Internalerror(2011051001);
|
Internalerror(2011051001);
|
||||||
|
|
||||||
|
{ check the hints for parseddef }
|
||||||
|
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);
|
||||||
isgeneric:=gendef<>generrordef;
|
isgeneric:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not isgeneric then
|
if not isgeneric then
|
||||||
p1:=caddnode.create(ltn,p1,p2)
|
begin
|
||||||
|
{ for potential generic types that are followed by a "<"
|
||||||
|
the hints are not checked }
|
||||||
|
if istypenode(p1) then
|
||||||
|
begin
|
||||||
|
gendef:=gettypedef(p1);
|
||||||
|
if gendef.typ in [objectdef,recorddef,arraydef,procvardef] then
|
||||||
|
check_hints(gendef.typesym,gendef.typesym.symoptions,gendef.typesym.deprecatedmsg);
|
||||||
|
end;
|
||||||
|
if istypenode(p2) and
|
||||||
|
(token in [_LT, _LSHARPBRACKET]) then
|
||||||
|
begin
|
||||||
|
gendef:=gettypedef(p2);
|
||||||
|
if gendef.typ in [objectdef,recorddef,arraydef,procvardef] then
|
||||||
|
check_hints(gendef.typesym,gendef.typesym.symoptions,gendef.typesym.deprecatedmsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ create the comparison node for "<" }
|
||||||
|
p1:=caddnode.create(ltn,p1,p2)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ 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;
|
||||||
p2.Free;
|
p2.Free;
|
||||||
{ in case of a class this is always a classrefdef }
|
{ in case of a class or a record the specialized generic
|
||||||
|
is always a classrefdef }
|
||||||
if is_class_or_interface_or_object(gendef) or
|
if is_class_or_interface_or_object(gendef) or
|
||||||
is_record(gendef) then
|
is_record(gendef) then
|
||||||
gendef:=tclassrefdef.create(gendef);
|
gendef:=tclassrefdef.create(gendef);
|
||||||
|
@ -48,6 +48,7 @@ uses
|
|||||||
{ modules }
|
{ modules }
|
||||||
fmodule,
|
fmodule,
|
||||||
{ pass 1 }
|
{ pass 1 }
|
||||||
|
htypechk,
|
||||||
node,nobj,
|
node,nobj,
|
||||||
{ parser }
|
{ parser }
|
||||||
scanner,
|
scanner,
|
||||||
@ -332,9 +333,12 @@ uses
|
|||||||
tt.typesym:=srsym;
|
tt.typesym:=srsym;
|
||||||
|
|
||||||
case tt.typ of
|
case tt.typ of
|
||||||
{ Build VMT indexes for classes }
|
{ Build VMT indexes for classes and read hint directives }
|
||||||
objectdef:
|
objectdef:
|
||||||
begin
|
begin
|
||||||
|
try_consume_hintdirective(srsym.symoptions,srsym.deprecatedmsg);
|
||||||
|
consume(_SEMICOLON);
|
||||||
|
|
||||||
vmtbuilder:=TVMTBuilder.Create(tobjectdef(tt));
|
vmtbuilder:=TVMTBuilder.Create(tobjectdef(tt));
|
||||||
vmtbuilder.generate_vmt;
|
vmtbuilder.generate_vmt;
|
||||||
vmtbuilder.free;
|
vmtbuilder.free;
|
||||||
@ -352,6 +356,12 @@ uses
|
|||||||
if try_consume_hintdirective(ttypesym(srsym).symoptions,ttypesym(srsym).deprecatedmsg) then
|
if try_consume_hintdirective(ttypesym(srsym).symoptions,ttypesym(srsym).deprecatedmsg) then
|
||||||
consume(_SEMICOLON);
|
consume(_SEMICOLON);
|
||||||
end;
|
end;
|
||||||
|
else
|
||||||
|
{ parse hint directives for records and arrays }
|
||||||
|
begin
|
||||||
|
try_consume_hintdirective(srsym.symoptions,srsym.deprecatedmsg);
|
||||||
|
consume(_SEMICOLON);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{ Consume the semicolon if it is also recorded }
|
{ Consume the semicolon if it is also recorded }
|
||||||
try_to_consume(_SEMICOLON);
|
try_to_consume(_SEMICOLON);
|
||||||
@ -384,7 +394,12 @@ uses
|
|||||||
genericdeflist.free;
|
genericdeflist.free;
|
||||||
generictypelist.free;
|
generictypelist.free;
|
||||||
if not try_to_consume(_GT) then
|
if not try_to_consume(_GT) then
|
||||||
consume(_RSHARPBRACKET);
|
consume(_RSHARPBRACKET)
|
||||||
|
else
|
||||||
|
if assigned(srsym) then
|
||||||
|
{ check the hints of the found generic symbol (this way we are
|
||||||
|
behind the closing ">") }
|
||||||
|
check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user