symppu.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  4. Implementation of the reading of PPU Files for the symtable
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symppu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,globals,
  23. symbase,symtype,
  24. ppu;
  25. type
  26. tcompilerppufile=class(tppufile)
  27. procedure checkerror;
  28. procedure getguid(var g: tguid);
  29. procedure getposinfo(var p:tfileposinfo);
  30. function getderef : pointer;
  31. function getsymlist:tsymlist;
  32. procedure gettype(var t:ttype);
  33. procedure putguid(const g: tguid);
  34. procedure putposinfo(const p:tfileposinfo);
  35. procedure putderef(p : tsymtableentry);
  36. procedure putsymlist(p:tsymlist);
  37. procedure puttype(const t:ttype);
  38. end;
  39. implementation
  40. uses
  41. symconst,
  42. verbose;
  43. {*****************************************************************************
  44. TCompilerPPUFile
  45. *****************************************************************************}
  46. procedure tcompilerppufile.checkerror;
  47. begin
  48. if error then
  49. Message(unit_f_ppu_read_error);
  50. end;
  51. procedure tcompilerppufile.getguid(var g: tguid);
  52. begin
  53. getdata(g,sizeof(g));
  54. end;
  55. procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
  56. var
  57. info : byte;
  58. begin
  59. {
  60. info byte layout in bits:
  61. 0-1 - amount of bytes for fileindex
  62. 2-3 - amount of bytes for line
  63. 4-5 - amount of bytes for column
  64. }
  65. info:=getbyte;
  66. case (info and $03) of
  67. 0 : p.fileindex:=getbyte;
  68. 1 : p.fileindex:=getword;
  69. 2 : p.fileindex:=(getbyte shl 16) or getword;
  70. 3 : p.fileindex:=getlongint;
  71. end;
  72. case ((info shr 2) and $03) of
  73. 0 : p.line:=getbyte;
  74. 1 : p.line:=getword;
  75. 2 : p.line:=(getbyte shl 16) or getword;
  76. 3 : p.line:=getlongint;
  77. end;
  78. case ((info shr 4) and $03) of
  79. 0 : p.column:=getbyte;
  80. 1 : p.column:=getword;
  81. 2 : p.column:=(getbyte shl 16) or getword;
  82. 3 : p.column:=getlongint;
  83. end;
  84. end;
  85. function tcompilerppufile.getderef : pointer;
  86. var
  87. hp,p : tderef;
  88. b : tdereftype;
  89. begin
  90. p:=nil;
  91. repeat
  92. hp:=p;
  93. b:=tdereftype(getbyte);
  94. case b of
  95. derefnil :
  96. break;
  97. derefunit,
  98. derefaktrecordindex,
  99. derefaktlocal,
  100. derefaktstaticindex :
  101. begin
  102. p:=tderef.create(b,getword);
  103. p.next:=hp;
  104. break;
  105. end;
  106. derefindex,
  107. dereflocal,
  108. derefpara,
  109. derefrecord :
  110. begin
  111. p:=tderef.create(b,getword);
  112. p.next:=hp;
  113. end;
  114. end;
  115. until false;
  116. getderef:=p;
  117. end;
  118. function tcompilerppufile.getsymlist:tsymlist;
  119. var
  120. sym : tsym;
  121. slt : tsltype;
  122. idx : longint;
  123. p : tsymlist;
  124. begin
  125. p:=tsymlist.create;
  126. p.def:=tdef(getderef);
  127. repeat
  128. slt:=tsltype(getbyte);
  129. case slt of
  130. sl_none :
  131. break;
  132. sl_call,
  133. sl_load,
  134. sl_subscript :
  135. begin
  136. sym:=tsym(getderef);
  137. p.addsym(slt,sym);
  138. end;
  139. sl_vec :
  140. begin
  141. idx:=getlongint;
  142. p.addconst(slt,idx);
  143. end;
  144. else
  145. internalerror(200110204);
  146. end;
  147. until false;
  148. getsymlist:=tsymlist(p);
  149. end;
  150. procedure tcompilerppufile.gettype(var t:ttype);
  151. begin
  152. t.def:=tdef(getderef);
  153. t.sym:=tsym(getderef);
  154. end;
  155. procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
  156. var
  157. oldcrc : boolean;
  158. info : byte;
  159. begin
  160. { posinfo is not relevant for changes in PPU }
  161. oldcrc:=do_crc;
  162. do_crc:=false;
  163. {
  164. info byte layout in bits:
  165. 0-1 - amount of bytes for fileindex
  166. 2-3 - amount of bytes for line
  167. 4-5 - amount of bytes for column
  168. }
  169. info:=0;
  170. { calculate info byte }
  171. if (p.fileindex>$ff) then
  172. begin
  173. if (p.fileindex<=$ffff) then
  174. info:=info or $1
  175. else
  176. if (p.fileindex<=$ffffff) then
  177. info:=info or $2
  178. else
  179. info:=info or $3;
  180. end;
  181. if (p.line>$ff) then
  182. begin
  183. if (p.line<=$ffff) then
  184. info:=info or $4
  185. else
  186. if (p.line<=$ffffff) then
  187. info:=info or $8
  188. else
  189. info:=info or $c;
  190. end;
  191. if (p.column>$ff) then
  192. begin
  193. if (p.column<=$ffff) then
  194. info:=info or $10
  195. else
  196. if (p.column<=$ffffff) then
  197. info:=info or $20
  198. else
  199. info:=info or $30;
  200. end;
  201. { write data }
  202. putbyte(info);
  203. case (info and $03) of
  204. 0 : putbyte(p.fileindex);
  205. 1 : putword(p.fileindex);
  206. 2 : begin
  207. putbyte(p.fileindex shr 16);
  208. putword(p.fileindex and $ffff);
  209. end;
  210. 3 : putlongint(p.fileindex);
  211. end;
  212. case ((info shr 2) and $03) of
  213. 0 : putbyte(p.line);
  214. 1 : putword(p.line);
  215. 2 : begin
  216. putbyte(p.line shr 16);
  217. putword(p.line and $ffff);
  218. end;
  219. 3 : putlongint(p.line);
  220. end;
  221. case ((info shr 4) and $03) of
  222. 0 : putbyte(p.column);
  223. 1 : putword(p.column);
  224. 2 : begin
  225. putbyte(p.column shr 16);
  226. putword(p.column and $ffff);
  227. end;
  228. 3 : putlongint(p.column);
  229. end;
  230. do_crc:=oldcrc;
  231. end;
  232. procedure tcompilerppufile.putguid(const g: tguid);
  233. begin
  234. putdata(g,sizeof(g));
  235. end;
  236. procedure tcompilerppufile.putderef(p : tsymtableentry);
  237. begin
  238. if p=nil then
  239. putbyte(ord(derefnil))
  240. else
  241. begin
  242. { Static symtable ? }
  243. if p.owner.symtabletype=staticsymtable then
  244. begin
  245. putbyte(ord(derefaktstaticindex));
  246. putword(p.indexnr);
  247. end
  248. { Local record/object symtable ? }
  249. else if (p.owner=aktrecordsymtable) then
  250. begin
  251. putbyte(ord(derefaktrecordindex));
  252. putword(p.indexnr);
  253. end
  254. { Local local/para symtable ? }
  255. else if (p.owner=aktlocalsymtable) then
  256. begin
  257. putbyte(ord(derefaktlocal));
  258. putword(p.indexnr);
  259. end
  260. else
  261. begin
  262. putbyte(ord(derefindex));
  263. putword(p.indexnr);
  264. { Current unit symtable ? }
  265. repeat
  266. if not assigned(p) then
  267. internalerror(556655);
  268. case p.owner.symtabletype of
  269. { when writing the pseudo PPU file
  270. to get CRC values the globalsymtable is not yet
  271. a unitsymtable PM }
  272. globalsymtable :
  273. begin
  274. { check if the unit is available in the uses
  275. clause, else it's an error }
  276. if p.owner.unitid=$ffff then
  277. internalerror(55665566);
  278. putbyte(ord(derefunit));
  279. putword(p.owner.unitid);
  280. break;
  281. end;
  282. staticsymtable :
  283. begin
  284. putbyte(ord(derefaktstaticindex));
  285. putword(p.indexnr);
  286. break;
  287. end;
  288. localsymtable :
  289. begin
  290. p:=p.owner.defowner;
  291. putbyte(ord(dereflocal));
  292. putword(p.indexnr);
  293. end;
  294. parasymtable :
  295. begin
  296. p:=p.owner.defowner;
  297. putbyte(ord(derefpara));
  298. putword(p.indexnr);
  299. end;
  300. objectsymtable,
  301. recordsymtable :
  302. begin
  303. p:=p.owner.defowner;
  304. putbyte(ord(derefrecord));
  305. putword(p.indexnr);
  306. end;
  307. else
  308. internalerror(556656);
  309. end;
  310. until false;
  311. end;
  312. end;
  313. end;
  314. procedure tcompilerppufile.putsymlist(p:tsymlist);
  315. var
  316. hp : psymlistitem;
  317. begin
  318. putderef(p.def);
  319. hp:=p.firstsym;
  320. while assigned(hp) do
  321. begin
  322. putbyte(byte(hp^.sltype));
  323. case hp^.sltype of
  324. sl_call,
  325. sl_load,
  326. sl_subscript :
  327. putderef(hp^.sym);
  328. sl_vec :
  329. putlongint(hp^.value);
  330. else
  331. internalerror(200110205);
  332. end;
  333. hp:=hp^.next;
  334. end;
  335. putbyte(byte(sl_none));
  336. end;
  337. procedure tcompilerppufile.puttype(const t:ttype);
  338. begin
  339. { Don't write symbol references for the current unit
  340. and for the system unit }
  341. if assigned(t.sym) and
  342. (t.sym.owner.unitid<>0) and
  343. (t.sym.owner.unitid<>1) then
  344. begin
  345. putderef(nil);
  346. putderef(t.sym);
  347. end
  348. else
  349. begin
  350. putderef(t.def);
  351. putderef(nil);
  352. end;
  353. end;
  354. end.
  355. {
  356. $Log$
  357. Revision 1.12 2002-05-18 13:34:18 peter
  358. * readded missing revisions
  359. Revision 1.11 2002/05/16 19:46:45 carl
  360. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  361. + try to fix temp allocation (still in ifdef)
  362. + generic constructor calls
  363. + start of tassembler / tmodulebase class cleanup
  364. Revision 1.9 2002/05/12 16:53:15 peter
  365. * moved entry and exitcode to ncgutil and cgobj
  366. * foreach gets extra argument for passing local data to the
  367. iterator function
  368. * -CR checks also class typecasts at runtime by changing them
  369. into as
  370. * fixed compiler to cycle with the -CR option
  371. * fixed stabs with elf writer, finally the global variables can
  372. be watched
  373. * removed a lot of routines from cga unit and replaced them by
  374. calls to cgobj
  375. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  376. u32bit then the other is typecasted also to u32bit without giving
  377. a rangecheck warning/error.
  378. * fixed pascal calling method with reversing also the high tree in
  379. the parast, detected by tcalcst3 test
  380. Revision 1.8 2002/04/19 15:40:40 peter
  381. * optimize tfileposinfo writing, this reduces the ppu size with 20%
  382. }