nllvmcal.pas 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. {
  2. Copyright (c) 2014 by Jonas Maebe
  3. Generate LLVM bytecode for call 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 nllvmcal;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. parabase,
  22. ncal,ncgcal,
  23. cgutils;
  24. type
  25. tllvmcallparanode = class(tcgcallparanode)
  26. protected
  27. function push_zero_sized_value_para: boolean; override;
  28. end;
  29. tllvmcallnode = class(tcgcallnode)
  30. protected
  31. function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override;
  32. function can_call_ref(var ref: treference): boolean; override;
  33. procedure pushparas; override;
  34. end;
  35. implementation
  36. uses
  37. verbose,
  38. symconst,symdef;
  39. {*****************************************************************************
  40. TLLVMCALLPARANODE
  41. *****************************************************************************}
  42. function tllvmcallparanode.push_zero_sized_value_para: boolean;
  43. begin
  44. { part of the signature -> need to be pushed }
  45. result:=true;
  46. end;
  47. {*****************************************************************************
  48. TLLVMCALLNODE
  49. *****************************************************************************}
  50. function tllvmcallnode.paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean;
  51. begin
  52. { We don't insert type conversions for self node trees to the type of
  53. the self parameter (and doing so is quite hard due to all kinds of
  54. ugly hacks with this parameter). This means that if we pass on a
  55. self parameter through multiple levels of inlining, it may no
  56. longer match the actual type of the parameter it has been passed to
  57. -> always store in a temp which by definition will have the right
  58. type (if it's a pointer-like type) }
  59. if (vo_is_self in para.parasym.varoptions) and
  60. (is_class_or_interface_or_dispinterface(para.parasym.vardef) or
  61. is_classhelper(para.parasym.vardef) or
  62. ((para.parasym.vardef.typ=classrefdef) and
  63. is_class(tclassrefdef(para.parasym.vardef).pointeddef))) then
  64. result:=true
  65. else
  66. result:=inherited;
  67. end;
  68. function tllvmcallnode.can_call_ref(var ref: treference): boolean;
  69. begin
  70. result:=false;
  71. end;
  72. procedure tllvmcallnode.pushparas;
  73. var
  74. n: tcgcallparanode;
  75. paraindex: longint;
  76. begin
  77. { we just pass the temp paralocs here }
  78. if not assigned(varargsparas) then
  79. setlength(paralocs,procdefinition.paras.count)
  80. else
  81. setlength(paralocs,procdefinition.paras.count+varargsparas.count);
  82. n:=tcgcallparanode(left);
  83. while assigned(n) do
  84. begin
  85. { TODO: check whether this is correct for left-to-right calling
  86. conventions, may also depend on whether or not llvm knows about
  87. the calling convention }
  88. if not(cpf_varargs_para in n.callparaflags) then
  89. paraindex:=procdefinition.paras.indexof(n.parasym)
  90. else
  91. paraindex:=procdefinition.paras.count+varargsparas.indexof(n.parasym);
  92. if paraindex=-1 then
  93. internalerror(2014010602);
  94. paralocs[paraindex]:[email protected];
  95. n:=tcgcallparanode(n.right);
  96. end;
  97. end;
  98. begin
  99. ccallnode:=tllvmcallnode;
  100. end.