nllvmcal.pas 3.8 KB

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