mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 12:10:26 +02:00
* The "Val" intrinsic is now simplified for string constants akin to a
pure function.
This commit is contained in:
parent
a9316b1953
commit
6597f02ebc
@ -2734,6 +2734,9 @@ implementation
|
||||
maxlennode, outnode, valnode: TNode;
|
||||
MaxStrLen: Int64;
|
||||
StringLiteral: string;
|
||||
ValOutput: TConstExprInt;
|
||||
ValCode: TCGInt;
|
||||
NewStatements: TStatementNode;
|
||||
begin
|
||||
result := nil;
|
||||
case intrinsiccode of
|
||||
@ -2802,6 +2805,69 @@ implementation
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
in_val_x:
|
||||
begin
|
||||
{ rare optimization opportunity which takes some extra time,
|
||||
so check only at level 3+ }
|
||||
if not(cs_opt_level3 in current_settings.optimizerswitches) then
|
||||
exit;
|
||||
{ If the input is a constant, attempt to convert, for example:
|
||||
"Val('5', Output, Code);" to "Output := 5; Code := 0;" }
|
||||
|
||||
{ Format of the internal function fpc_val_sint_*str) is:
|
||||
fpc_val_sint_*str(SizeInt; *String; out ValSInt): ValSInt; }
|
||||
|
||||
{ Remember the parameters are in reverse order - the leftmost one
|
||||
is the integer data size can usually be ignored.
|
||||
|
||||
For fpc_val_uint_*str variants, the data size is not present as
|
||||
of FPC 3.2.0
|
||||
|
||||
Para indices:
|
||||
* 0 = Code output (present even if omitted in original code)
|
||||
* 1 = String input
|
||||
* 2 = Data size
|
||||
}
|
||||
para := GetParaFromIndex(0);
|
||||
if Assigned(para) then
|
||||
begin
|
||||
outnode := para.left;
|
||||
para := GetParaFromIndex(1);
|
||||
if Assigned(para) then
|
||||
begin
|
||||
valnode := para.left;
|
||||
if is_conststringnode(valnode) then
|
||||
begin
|
||||
ValOutput.signed := is_signed(ResultDef);
|
||||
if ValOutput.signed then
|
||||
Val(TStringConstNode(valnode).value_str, ValOutput.svalue, ValCode)
|
||||
else
|
||||
Val(TStringConstNode(valnode).value_str, ValOutput.uvalue, ValCode);
|
||||
|
||||
{ Due to the way the node tree works, we have to insert
|
||||
the assignment to the Code output within the
|
||||
assignment to the value output (function result),
|
||||
so use a block node for that}
|
||||
|
||||
Result := internalstatements(NewStatements);
|
||||
|
||||
{ Create a node for writing the Code output }
|
||||
addstatement(
|
||||
NewStatements,
|
||||
CAssignmentNode.Create_Internal(
|
||||
outnode.getcopy(), { The original will get destroyed }
|
||||
COrdConstNode.Create(ValCode, outnode.ResultDef, False)
|
||||
)
|
||||
);
|
||||
|
||||
{ Now actually create the function result }
|
||||
valnode := COrdConstNode.Create(ValOutput, ResultDef, False);
|
||||
addstatement(NewStatements, valnode);
|
||||
{ Result will now undergo firstpass }
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
;
|
||||
end;
|
||||
|
@ -1765,9 +1765,9 @@ implementation
|
||||
if (destpara.resultdef.typ=enumdef) or
|
||||
((destpara.resultdef.typ=floatdef) and (tfloatdef(destpara.resultdef).floattype=s64comp))
|
||||
then
|
||||
tc:=ccallnode.createintern(procname,newparas)
|
||||
tc:=ccallnode.createfromintrinsic(in_val_x,procname,newparas)
|
||||
else
|
||||
tc:=ctypeconvnode.create(ccallnode.createintern(procname,newparas),destpara.left.resultdef);
|
||||
tc:=ctypeconvnode.create(ccallnode.createfromintrinsic(in_val_x,procname,newparas),destpara.left.resultdef);
|
||||
addstatement(newstatement,cassignmentnode.create(
|
||||
destpara.left,ctypeconvnode.create_internal(tc,destpara.left.resultdef)));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user