ncgobjc.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. {
  2. Copyright (c) 2009 by Jonas Maebe
  3. This unit implements code generator support for Objective-C nodes
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit ncgobjc;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. nobjc;
  22. type
  23. tcgobjcselectornode = class(tobjcselectornode)
  24. procedure pass_generate_code; override;
  25. end;
  26. implementation
  27. uses
  28. globtype,cclasses,
  29. aasmbase,aasmdata,aasmtai,
  30. cgbase,cgutils,defutil,
  31. symsym,
  32. node,nld,ncon,
  33. verbose;
  34. {*****************************************************************************
  35. TCGOBJCSELECTORNODE
  36. *****************************************************************************}
  37. procedure tcgobjcselectornode.pass_generate_code;
  38. var
  39. reflab,
  40. strlab : tasmlabel;
  41. pool : THashSet;
  42. entry : PHashSetItem;
  43. name : string;
  44. pc : pchar;
  45. begin
  46. if current_asmdata.ConstPools[sp_objcselector] = nil then
  47. current_asmdata.ConstPools[sp_objcselector] := THashSet.Create(64, True, False);
  48. pool := current_asmdata.ConstPools[sp_objcselector];
  49. case left.nodetype of
  50. loadn:
  51. begin
  52. name:=tprocsym(tloadnode(left).symtableentry).mangledname;
  53. entry := pool.FindOrAdd(@name[1],length(name))
  54. end;
  55. stringconstn:
  56. begin
  57. entry := pool.FindOrAdd(tstringconstnode(left).value_str, tstringconstnode(left).len);
  58. end;
  59. else
  60. internalerror(2009030701);
  61. end;
  62. { have we already generated this selector? }
  63. if not assigned(entry^.Data) then
  64. begin
  65. { create new one
  66. (no getdatalabel, because these labels have to be local)
  67. }
  68. current_asmdata.getlabel(reflab,alt_data);
  69. current_asmdata.getlabel(strlab,alt_data);
  70. entry^.Data := reflab;
  71. getmem(pc,entry^.keylength+1);
  72. move(entry^.key^,pc^,entry^.keylength);
  73. pc[entry^.keylength]:=#0;
  74. { add a pointer to the message name in the objc_message_refs section }
  75. new_section(current_asmdata.asmlists[al_objc_data],sec_objc_message_refs,reflab.name,sizeof(pint));
  76. current_asmdata.asmlists[al_objc_data].concat(Tai_label.Create(reflab));
  77. current_asmdata.asmlists[al_objc_data].concat(Tai_const.Create_sym(strlab));
  78. { and now add the message name to the meth_var_names }
  79. new_section(current_asmdata.asmlists[al_objc_data],sec_objc_meth_var_names,strlab.name,1);
  80. current_asmdata.asmlists[al_objc_data].concat(Tai_label.Create(strlab));
  81. current_asmdata.asmlists[al_objc_data].concat(Tai_string.Create_pchar(pc,entry^.keylength+1));
  82. end;
  83. location_reset_ref(location, LOC_CREFERENCE, def_cgsize(resultdef), sizeof(pint));
  84. location.reference.symbol:=tasmlabel(entry^.Data);
  85. end;
  86. begin
  87. cobjcselectornode:=tcgobjcselectornode;
  88. end.