ncgnstmm.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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,defutil,procdefutil,pparautl,symcreat,
  33. aasmbase,aasmtai,aasmdata,
  34. procinfo,pass_2,parabase,paramgr,
  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) or
  50. (assigned(current_procinfo) and
  51. (df_generic in current_procinfo.procdef.defoptions)) then
  52. exit;
  53. currpi:=current_procinfo.parent;
  54. { current_procinfo.parent is not assigned for specialised generic routines in the
  55. top-level scope }
  56. while assigned(currpi) and
  57. (currpi.procdef.parast.symtablelevel>=parentpd.parast.symtablelevel) do
  58. begin
  59. if not assigned(currpi.procdef.parentfpstruct) then
  60. build_parentfpstruct(currpi.procdef);
  61. currpi:=currpi.parent;
  62. end;
  63. { mark all parent parentfp parameters for inclusion in the struct that
  64. holds all locals accessed from nested routines }
  65. currpi:=current_procinfo.parent;
  66. if assigned(currpi) then
  67. begin
  68. nextpi:=currpi.parent;
  69. while assigned(currpi) and
  70. (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
  71. begin
  72. hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
  73. maybe_add_sym_to_parentfpstruct(currpi.procdef,hsym,nextpi.procdef.parentfpstructptrtype,false);
  74. currpi:=nextpi;
  75. nextpi:=nextpi.parent;
  76. end;
  77. end;
  78. end;
  79. function tcgnestloadparentfpnode.pass_1: tnode;
  80. var
  81. fsym : tfieldvarsym;
  82. hsym : tparavarsym;
  83. currpi : tprocinfo;
  84. useparentfppara : boolean;
  85. begin
  86. result:=nil;
  87. { if the current routine does not call a nested routine, or if that
  88. nested routine does nothing for which it needs the nestedfp pointer
  89. of the current routine (and hence it has not been moved into the
  90. nestedfp struct), get the original nestedfp parameter }
  91. useparentfppara:=not assigned(current_procinfo.procdef.parentfpstruct);
  92. hsym:=tparavarsym(current_procinfo.procdef.parast.Find('parentfp'));
  93. if current_procinfo.procdef.parast.symtablelevel>parentpd.parast.symtablelevel then
  94. useparentfppara:=
  95. useparentfppara or
  96. (find_sym_in_parentfpstruct(current_procinfo.procdef,hsym)=nil);
  97. if useparentfppara then
  98. begin
  99. result:=cloadnode.create(hsym,hsym.owner);
  100. currpi:=current_procinfo.parent;
  101. end
  102. else
  103. begin
  104. result:=caddrnode.create_internal(cloadnode.create(current_procinfo.procdef.parentfpstruct,current_procinfo.procdef.parentfpstruct.owner));
  105. include(taddrnode(result).addrnodeflags,anf_typedaddr);
  106. currpi:=current_procinfo;
  107. end;
  108. { follow the chain of parentfpstructs until we arrive at the one we
  109. need }
  110. while (currpi.procdef.parast.symtablelevel>parentpd.parast.symtablelevel) do
  111. begin
  112. hsym:=tparavarsym(currpi.procdef.parast.Find('parentfp'));
  113. fsym:=tfieldvarsym(find_sym_in_parentfpstruct(currpi.procdef,hsym));
  114. if not assigned(fsym) then
  115. internalerror(2011060405);
  116. result:=csubscriptnode.create(fsym,cderefnode.create(result));
  117. currpi:=currpi.parent;
  118. end;
  119. end;
  120. procedure tcgnestloadparentfpnode.pass_generate_code;
  121. begin
  122. { should be handled in pass 1 }
  123. internalerror(2011060202);
  124. end;
  125. begin
  126. cloadparentfpnode:=tcgnestloadparentfpnode;
  127. end.