ncgnstmm.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. ****************************************************************************
  15. }
  16. unit ncgnstmm;
  17. {$i fpcdefs.inc}
  18. interface
  19. uses
  20. globtype,cgbase,cpuinfo,cpubase,
  21. node,ncgmem;
  22. type
  23. tcgnestloadparentfpnode = class(tcgloadparentfpnode)
  24. function pass_typecheck: tnode; override;
  25. function pass_1: tnode; override;
  26. procedure pass_generate_code;override;
  27. end;
  28. implementation
  29. uses
  30. systems,
  31. cutils,cclasses,verbose,globals,constexp,
  32. symconst,symdef,symsym,symtable,symcreat,defutil,paramgr,
  33. aasmbase,aasmtai,aasmdata,
  34. procinfo,pass_2,parabase,
  35. pass_1,ncnv,nmem,nld,ncon,nadd,nutils,
  36. cgutils,cgobj,hlcgobj,
  37. tgobj,ncgutil,objcgutl
  38. ;
  39. {*****************************************************************************
  40. TCGLOADPARENTFPNODE
  41. *****************************************************************************}
  42. function tcgnestloadparentfpnode.pass_typecheck: tnode;
  43. var
  44. hsym : tparavarsym;
  45. currpi,
  46. nextpi : tprocinfo;
  47. begin
  48. result:=inherited;
  49. if assigned(result) then
  50. exit;
  51. currpi:=current_procinfo.parent;
  52. while (currpi.procdef.parast.symtablelevel>=parentpd.parast.symtablelevel) do
  53. begin
  54. if not assigned(currpi.procdef.parentfpstruct) then
  55. build_parentfpstruct(currpi.procdef);
  56. currpi:=currpi.parent;
  57. end;
  58. { mark all parent parentfp parameters for inclusion in the struct that
  59. holds all locals accessed from nested routines }
  60. currpi:=current_procinfo.parent;
  61. nextpi:=currpi.parent;
  62. while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
  63. begin
  64. hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
  65. maybe_add_sym_to_parentfpstruct(currpi.procdef,hsym,nextpi.procdef.parentfpstructptrtype,false);
  66. currpi:=nextpi;
  67. nextpi:=nextpi.parent;
  68. end;
  69. end;
  70. function tcgnestloadparentfpnode.pass_1: tnode;
  71. var
  72. fsym : tfieldvarsym;
  73. hsym : tparavarsym;
  74. currpi : tprocinfo;
  75. useparentfppara : boolean;
  76. begin
  77. result:=nil;
  78. { if the current routine does not call a nested routine, or if that
  79. nested routine does nothing for which it needs the nestedfp pointer
  80. of the current routine (and hence it has not been moved into the
  81. nestedfp struct), get the original nestedfp parameter }
  82. useparentfppara:=not assigned(current_procinfo.procdef.parentfpstruct);
  83. hsym:=tparavarsym(current_procinfo.procdef.parast.Find('parentfp'));
  84. if current_procinfo.procdef.parast.symtablelevel>parentpd.parast.symtablelevel then
  85. useparentfppara:=
  86. useparentfppara or
  87. (find_sym_in_parentfpstruct(current_procinfo.procdef,hsym)=nil);
  88. if useparentfppara then
  89. begin
  90. result:=cloadnode.create(hsym,hsym.owner);
  91. currpi:=current_procinfo.parent;
  92. end
  93. else
  94. begin
  95. result:=caddrnode.create_internal(cloadnode.create(current_procinfo.procdef.parentfpstruct,current_procinfo.procdef.parentfpstruct.owner));
  96. include(result.flags,nf_typedaddr);
  97. currpi:=current_procinfo;
  98. end;
  99. { follow the chain of parentfpstructs until we arrive at the one we
  100. need }
  101. while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
  102. begin
  103. hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
  104. fsym:=tfieldvarsym(find_sym_in_parentfpstruct(currpi.procdef,hsym));
  105. if not assigned(fsym) then
  106. internalerror(2011060405);
  107. result:=csubscriptnode.create(fsym,cderefnode.create(result));
  108. currpi:=currpi.parent;
  109. end;
  110. end;
  111. procedure tcgnestloadparentfpnode.pass_generate_code;
  112. begin
  113. { should be handled in pass 1 }
  114. internalerror(2011060202);
  115. end;
  116. begin
  117. cloadparentfpnode:=tcgnestloadparentfpnode;
  118. end.