tclatype.pp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. {$mode objfpc}
  2. type
  3. tbaseclass = class
  4. x : longint;
  5. function get_type : pointer;
  6. function get_type2 : pointer;virtual;
  7. procedure check_type;
  8. class procedure virtual_class_method;virtual;
  9. end;
  10. tderivedclass = class(tbaseclass)
  11. y : longint;
  12. function get_type2 : pointer;override;
  13. class procedure virtual_class_method;override;
  14. end;
  15. const
  16. tbasecalled : boolean = false;
  17. tderivedcalled : boolean = false;
  18. has_error : boolean = false;
  19. expected_size_for_tbaseclass = sizeof(pointer) + sizeof(longint);
  20. expected_size_for_tderivedclass = sizeof(pointer) + 2*sizeof(longint);
  21. var
  22. basesize : longint;
  23. derivedsize : longint;
  24. function tbaseclass.get_type : pointer;
  25. begin
  26. get_type:=typeof(self);
  27. end;
  28. function tbaseclass.get_type2 : pointer;
  29. begin
  30. get_type2:=typeof(self);
  31. end;
  32. procedure tbaseclass.check_type;
  33. begin
  34. if typeof(self)<>get_type then
  35. begin
  36. Writeln('Compiler creates garbage');
  37. has_error:=true;
  38. end;
  39. if typeof(self)<>get_type2 then
  40. begin
  41. Writeln('Compiler creates garbage');
  42. has_error:=true;
  43. end;
  44. if get_type<>get_type2 then
  45. begin
  46. Writeln('get_type and get_type2 return different pointers');
  47. has_error:=true;
  48. end;
  49. end;
  50. procedure tbaseclass.virtual_class_method;
  51. begin
  52. Writeln('Calling tbase class class method');
  53. tbasecalled:=true;
  54. if sizeof(self)<>basesize then
  55. begin
  56. has_error:=true;
  57. Writeln('Error with sizeof');
  58. end;
  59. end;
  60. function tderivedclass.get_type2 : pointer;
  61. begin
  62. get_type2:=typeof(self);
  63. end;
  64. procedure tderivedclass.virtual_class_method;
  65. begin
  66. Writeln('Calling tderived class class method');
  67. tderivedcalled:=true;
  68. if sizeof(self)<>derivedsize then
  69. begin
  70. has_error:=true;
  71. Writeln('Error with sizeof');
  72. end;
  73. end;
  74. procedure reset_booleans;
  75. begin
  76. tbasecalled:=false;
  77. tderivedcalled:=false;
  78. end;
  79. var
  80. c1,cb : tbaseclass;
  81. cd : tderivedclass;
  82. cc : class of tbaseclass;
  83. pb,pd : pointer;
  84. begin
  85. cb:=tbaseclass.create;
  86. cd:=tderivedclass.create;
  87. c1:=tbaseclass.create;
  88. basesize:=sizeof(cb);
  89. Writeln('Sizeof(cb)=',basesize);
  90. if basesize<>sizeof(pointer) then
  91. Writeln('not the expected size : ',sizeof(pointer));
  92. derivedsize:=sizeof(cd);
  93. Writeln('Sizeof(ct)=',derivedsize);
  94. if derivedsize<>sizeof(pointer) then
  95. Writeln('not the expected size : ',sizeof(pointer));
  96. cb.check_type;
  97. cd.check_type;
  98. c1.destroy;
  99. c1:=tderivedclass.create;
  100. c1.virtual_class_method;
  101. if not tderivedcalled then
  102. has_error:=true;
  103. reset_booleans;
  104. c1.destroy;
  105. cc:=tbaseclass;
  106. cc.virtual_class_method;
  107. if not tbasecalled then
  108. has_error:=true;
  109. reset_booleans;
  110. cc:=tderivedclass;
  111. cc.virtual_class_method;
  112. if not tderivedcalled then
  113. has_error:=true;
  114. reset_booleans;
  115. if has_error then
  116. begin
  117. Writeln('Error with class methods');
  118. halt(1);
  119. end;
  120. end.