pdecl.pas 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Does declaration parsing for Free Pascal
  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 pdecl;
  19. interface
  20. uses
  21. globals,symtable;
  22. var
  23. { pointer to the last read type symbol, (for "forward" }
  24. { types) }
  25. lasttypesym : ptypesym;
  26. { hack, which allows to use the current parsed }
  27. { object type as function argument type }
  28. testcurobject : byte;
  29. curobjectname : stringid;
  30. { reads a string type with optional length }
  31. { and returns a pointer to the string }
  32. { definition }
  33. function stringtype : pdef;
  34. { reads a string, file type or a type id and returns a name and }
  35. { pdef }
  36. function single_type(var s : string) : pdef;
  37. { reads the declaration blocks }
  38. procedure read_declarations(islibrary : boolean);
  39. { reads declarations in the interface part of a unit }
  40. procedure read_interface_declarations;
  41. implementation
  42. uses
  43. cobjects,scanner,aasm,tree,pass_1,
  44. files,types,hcodegen,verbose,systems
  45. {$ifdef GDB}
  46. ,gdb
  47. {$endif GDB}
  48. { parser specific stuff }
  49. ,pbase,ptconst,pexpr,psub,pexports
  50. { processor specific stuff }
  51. {$ifdef i386}
  52. ,i386
  53. {$endif}
  54. {$ifdef m68k}
  55. ,m68k
  56. {$endif}
  57. ;
  58. function read_type(const name : stringid) : pdef;forward;
  59. procedure read_var_decs(is_record : boolean;do_absolute : boolean);forward;
  60. procedure const_dec;
  61. var
  62. name : stringid;
  63. p : ptree;
  64. def : pdef;
  65. sym : psym;
  66. ps : pconstset;
  67. pd : pdouble;
  68. begin
  69. consume(_CONST);
  70. repeat
  71. name:=pattern;
  72. consume(ID);
  73. case token of
  74. EQUAL:
  75. begin
  76. consume(EQUAL);
  77. p:=comp_expr(true);
  78. do_firstpass(p);
  79. case p^.treetype of
  80. ordconstn:
  81. begin
  82. if is_constintnode(p) then
  83. symtablestack^.insert(new(pconstsym,init(name,constint,p^.value,nil)))
  84. else if is_constcharnode(p) then
  85. symtablestack^.insert(new(pconstsym,init(name,constchar,p^.value,nil)))
  86. else if is_constboolnode(p) then
  87. symtablestack^.insert(new(pconstsym,init(name,constbool,p^.value,nil)))
  88. else if p^.resulttype^.deftype=enumdef then
  89. symtablestack^.insert(new(pconstsym,init(name,constord,p^.value,p^.resulttype)))
  90. else internalerror(111);
  91. end;
  92. stringconstn:
  93. {values is disposed with p so I need a copy !}
  94. symtablestack^.insert(new(pconstsym,init(name,conststring,longint(stringdup(p^.values^)),nil)));
  95. realconstn : begin
  96. new(pd);
  97. pd^:=p^.valued;
  98. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd),nil)));
  99. end;
  100. setconstrn : begin
  101. new(ps);
  102. ps^:=p^.constset^;
  103. symtablestack^.insert(new(pconstsym,init(name,
  104. constseta,longint(ps),p^.resulttype)));
  105. end;
  106. else Message(cg_e_illegal_expression);
  107. end;
  108. consume(SEMICOLON);
  109. end;
  110. COLON:
  111. begin
  112. { this was missed, so const s : ^string = nil gives an
  113. error (FK)
  114. }
  115. block_type:=bt_type;
  116. consume(COLON);
  117. ignore_equal:=true;
  118. def:=read_type('');
  119. block_type:=bt_general;
  120. ignore_equal:=false;
  121. sym:=new(ptypedconstsym,init(name,def));
  122. symtablestack^.insert(sym);
  123. consume(EQUAL);
  124. readtypedconst(def,ptypedconstsym(sym));
  125. consume(SEMICOLON);
  126. end;
  127. else consume(EQUAL);
  128. end;
  129. until token<>ID;
  130. end;
  131. procedure label_dec;
  132. var
  133. hl : plabel;
  134. begin
  135. consume(_LABEL);
  136. if not(cs_support_goto in aktswitches) then
  137. Message(sym_e_goto_and_label_not_supported);
  138. repeat
  139. if not(token in [ID,INTCONST]) then
  140. consume(ID)
  141. else
  142. begin
  143. getlabel(hl);
  144. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  145. consume(token);
  146. end;
  147. if token<>SEMICOLON then consume(COMMA);
  148. until not(token in [ID,INTCONST]);
  149. consume(SEMICOLON);
  150. end;
  151. { reads a string type with optional length }
  152. { and returns a pointer to the string }
  153. { definition }
  154. function stringtype : pdef;
  155. var
  156. p : ptree;
  157. d : pdef;
  158. begin
  159. consume(_STRING);
  160. if token=LECKKLAMMER then
  161. begin
  162. consume(LECKKLAMMER);
  163. p:=comp_expr(true);
  164. do_firstpass(p);
  165. if not is_constintnode(p) then
  166. Message(cg_e_illegal_expression);
  167. {$ifndef UseAnsiString}
  168. if (p^.value<1) or (p^.value>255) then
  169. begin
  170. Message(parser_e_string_too_long);
  171. p^.value:=255;
  172. end;
  173. consume(RECKKLAMMER);
  174. if p^.value<>255 then
  175. d:=new(pstringdef,init(p^.value))
  176. {$ifndef GDB}
  177. else d:=new(pstringdef,init(255));
  178. {$else * GDB *}
  179. else d:=globaldef('SYSTEM.STRING');
  180. {$endif * GDB *}
  181. {$else UseAnsiString}
  182. if p^.value>255 then
  183. d:=new(pstringdef,ansiinit(p^.value))
  184. else if p^.value<>255 then
  185. d:=new(pstringdef,init(p^.value))
  186. {$ifndef GDB}
  187. else d:=new(pstringdef,init(255));
  188. {$else * GDB *}
  189. else d:=globaldef('SYSTEM.STRING');
  190. {$endif * GDB *}
  191. consume(RECKKLAMMER);
  192. {$endif UseAnsiString}
  193. disposetree(p);
  194. end
  195. { should string bwithout suffix be an ansistring also
  196. in ansistring mode ?? (PM) }
  197. {$ifndef GDB}
  198. else d:=new(pstringdef,init(255));
  199. {$else * GDB *}
  200. else d:=globaldef('SYSTEM.STRING');
  201. {$endif * GDB *}
  202. stringtype:=d;
  203. end;
  204. { reads a type definition and returns a pointer }
  205. { to a appropriating pdef, s gets the name of }
  206. { the type to allow name mangling }
  207. function id_type(var s : string) : pdef;
  208. begin
  209. s:=pattern;
  210. consume(ID);
  211. { classes can be used also in classes }
  212. if (curobjectname=pattern) and aktobjectdef^.isclass then
  213. begin
  214. id_type:=aktobjectdef;
  215. exit;
  216. end;
  217. { objects can be parameters }
  218. if (testcurobject=2) and (curobjectname=pattern) then
  219. begin
  220. id_type:=aktobjectdef;
  221. exit;
  222. end;
  223. getsym(s,true);
  224. if assigned(srsym) then
  225. begin
  226. if srsym^.typ=unitsym then
  227. begin
  228. consume(POINT);
  229. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  230. s:=pattern;
  231. consume(ID);
  232. end;
  233. if srsym^.typ<>typesym then
  234. begin
  235. Message(sym_e_type_id_expected);
  236. lasttypesym:=ptypesym(srsym);
  237. id_type:=generrordef;
  238. exit;
  239. end;
  240. end;
  241. lasttypesym:=ptypesym(srsym);
  242. id_type:=ptypesym(srsym)^.definition;
  243. end;
  244. { reads a string, file type or a type id and returns a name and }
  245. { pdef }
  246. function single_type(var s : string) : pdef;
  247. var
  248. hs : string;
  249. begin
  250. case token of
  251. _STRING:
  252. begin
  253. single_type:=stringtype;
  254. s:='STRING';
  255. lasttypesym:=nil;
  256. end;
  257. _FILE:
  258. begin
  259. consume(_FILE);
  260. if token=_OF then
  261. begin
  262. consume(_OF);
  263. single_type:=new(pfiledef,init(ft_typed,single_type(hs)));
  264. s:='FILE$OF$'+hs;
  265. end
  266. else
  267. begin
  268. { single_type:=new(pfiledef,init(ft_untyped,nil));}
  269. single_type:=cfiledef;
  270. s:='FILE';
  271. end;
  272. lasttypesym:=nil;
  273. end;
  274. else single_type:=id_type(s);
  275. end;
  276. end;
  277. { this function parses an object or class declaration }
  278. function object_dec(const n : stringid;fd : pobjectdef) : pdef;
  279. var
  280. actmembertype : symprop;
  281. there_is_a_destructor : boolean;
  282. is_a_class : boolean;
  283. childof : pobjectdef;
  284. aktclass : pobjectdef;
  285. procedure constructor_head;
  286. begin
  287. consume(_CONSTRUCTOR);
  288. { must be at same level as in implementation }
  289. _proc_head(poconstructor);
  290. if (cs_checkconsname in aktswitches) and (aktprocsym^.name<>'INIT') then
  291. Message(parser_e_constructorname_must_be_init);
  292. consume(SEMICOLON);
  293. begin
  294. if (aktclass^.options and oois_class)<>0 then
  295. begin
  296. { CLASS constructors return the created instance }
  297. aktprocsym^.definition^.retdef:=aktclass;
  298. end
  299. else
  300. begin
  301. { OBJECT constructors return a boolean }
  302. {$IfDef GDB}
  303. {GDB doesn't like unnamed types !}
  304. aktprocsym^.definition^.retdef:=
  305. globaldef('boolean');
  306. {$Else * GDB *}
  307. aktprocsym^.definition^.retdef:=
  308. new(porddef,init(bool8bit,0,1));
  309. {$Endif * GDB *}
  310. end;
  311. end;
  312. end;
  313. procedure property_dec;
  314. var
  315. sym : psym;
  316. propertyparas : pdefcoll;
  317. { returns the matching procedure to access a property }
  318. function get_procdef : pprocdef;
  319. var
  320. p : pprocdef;
  321. begin
  322. p:=pprocsym(sym)^.definition;
  323. get_procdef:=nil;
  324. while assigned(p) do
  325. begin
  326. if equal_paras(p^.para1,propertyparas,true) then
  327. break;
  328. p:=p^.nextoverloaded;
  329. end;
  330. get_procdef:=p;
  331. end;
  332. var
  333. hp2,datacoll : pdefcoll;
  334. p,p2 : ppropertysym;
  335. overriden : psym;
  336. hs : string;
  337. code : word;
  338. varspez : tvarspez;
  339. sc : pstringcontainer;
  340. hp : pdef;
  341. s : string;
  342. {$ifdef UseTokenInfo}
  343. filepos : tfileposinfo;
  344. {$endif UseTokenInfo}
  345. pp : pprocdef;
  346. begin
  347. { check for a class }
  348. if (aktclass^.options and oois_class=0) then
  349. Message(parser_e_syntax_error);
  350. consume(_PROPERTY);
  351. if token=ID then
  352. begin
  353. p:=new(ppropertysym,init(pattern));
  354. consume(ID);
  355. propertyparas:=nil;
  356. datacoll:=nil;
  357. { property parameters ? }
  358. if token=LECKKLAMMER then
  359. begin
  360. { create a list of the parameters in propertyparas }
  361. consume(LECKKLAMMER);
  362. inc(testcurobject);
  363. repeat
  364. if token=_VAR then
  365. begin
  366. consume(_VAR);
  367. varspez:=vs_var;
  368. end
  369. else if token=_CONST then
  370. begin
  371. consume(_CONST);
  372. varspez:=vs_const;
  373. end
  374. else varspez:=vs_value;
  375. sc:=idlist;
  376. if token=COLON then
  377. begin
  378. consume(COLON);
  379. if token=_ARRAY then
  380. begin
  381. {
  382. if (varspez<>vs_const) and
  383. (varspez<>vs_var) then
  384. begin
  385. varspez:=vs_const;
  386. Message(parser_e_illegal_open_parameter);
  387. end;
  388. }
  389. consume(_ARRAY);
  390. consume(_OF);
  391. { define range and type of range }
  392. hp:=new(parraydef,init(0,-1,s32bitdef));
  393. { define field type }
  394. parraydef(hp)^.definition:=single_type(s);
  395. end
  396. else
  397. hp:=single_type(s);
  398. end
  399. else
  400. hp:=new(pformaldef,init);
  401. s:=sc^.get;
  402. while s<>'' do
  403. begin
  404. new(hp2);
  405. hp2^.paratyp:=varspez;
  406. hp2^.data:=hp;
  407. hp2^.next:=propertyparas;
  408. propertyparas:=hp2;
  409. s:=sc^.get;
  410. end;
  411. dispose(sc,done);
  412. if token=SEMICOLON then consume(SEMICOLON)
  413. else break;
  414. until false;
  415. dec(testcurobject);
  416. consume(RECKKLAMMER);
  417. end;
  418. { overriden property ? }
  419. { force property interface, if there is a property parameter }
  420. if (token=COLON) or assigned(propertyparas) then
  421. begin
  422. consume(COLON);
  423. p^.proptype:=single_type(hs);
  424. if (token=ID) and (pattern='INDEX') then
  425. begin
  426. consume(ID);
  427. p^.options:=p^.options or ppo_indexed;
  428. if token=INTCONST then
  429. val(pattern,p^.index,code);
  430. consume(INTCONST);
  431. { concat a longint to the para template }
  432. new(hp2);
  433. hp2^.paratyp:=vs_value;
  434. hp2^.data:=s32bitdef;
  435. hp2^.next:=propertyparas;
  436. propertyparas:=hp2;
  437. end;
  438. end
  439. else
  440. begin
  441. { do an property override }
  442. overriden:=search_class_member(aktclass,pattern);
  443. if assigned(overriden) and (overriden^.typ=propertysym) then
  444. begin
  445. { take the whole info: }
  446. p^.options:=ppropertysym(overriden)^.options;
  447. p^.index:=ppropertysym(overriden)^.index;
  448. p^.proptype:=ppropertysym(overriden)^.proptype;
  449. p^.writeaccesssym:=ppropertysym(overriden)^.writeaccesssym;
  450. p^.readaccesssym:=ppropertysym(overriden)^.readaccesssym;
  451. p^.writeaccessdef:=ppropertysym(overriden)^.writeaccessdef;
  452. p^.readaccessdef:=ppropertysym(overriden)^.readaccessdef;
  453. end
  454. else
  455. begin
  456. p^.proptype:=generrordef;
  457. message(parser_e_no_property_found_to_override);
  458. end;
  459. end;
  460. { create data defcoll to allow correct parameter checks }
  461. new(datacoll);
  462. datacoll^.paratyp:=vs_value;
  463. datacoll^.data:=p^.proptype;
  464. datacoll^.next:=nil;
  465. if (token=ID) and (pattern='READ') then
  466. begin
  467. consume(ID);
  468. sym:=search_class_member(aktclass,pattern);
  469. if not(assigned(sym)) then
  470. Message1(sym_e_unknown_id,pattern)
  471. else
  472. begin
  473. { varsym aren't allowed for an indexed property
  474. or an property with parameters }
  475. if ((sym^.typ=varsym) and
  476. { not necessary, an index forces propertyparas
  477. to be assigned
  478. }
  479. { (((p^.options and ppo_indexed)<>0) or }
  480. assigned(propertyparas)) or
  481. not(sym^.typ in [varsym,procsym]) then
  482. Message(parser_e_ill_property_access_sym);
  483. { search the matching definition }
  484. if sym^.typ=procsym then
  485. begin
  486. pp:=get_procdef;
  487. if not(assigned(pp)) or
  488. not(is_equal(pp^.retdef,p^.proptype)) then
  489. Message(parser_e_ill_property_access_sym);
  490. p^.readaccessdef:=pp;
  491. end
  492. else if sym^.typ=varsym then
  493. begin
  494. if not(is_equal(pvarsym(sym)^.definition,
  495. p^.proptype)) then
  496. Message(parser_e_ill_property_access_sym);
  497. end;
  498. p^.readaccesssym:=sym;
  499. end;
  500. consume(ID);
  501. end;
  502. if (token=ID) and (pattern='WRITE') then
  503. begin
  504. consume(ID);
  505. sym:=search_class_member(aktclass,pattern);
  506. if not(assigned(sym)) then
  507. Message1(sym_e_unknown_id,pattern)
  508. else
  509. begin
  510. if ((sym^.typ=varsym) and
  511. assigned(propertyparas)) or
  512. not(sym^.typ in [varsym,procsym]) then
  513. Message(parser_e_ill_property_access_sym);
  514. { search the matching definition }
  515. if sym^.typ=procsym then
  516. begin
  517. { insert data entry to check access method }
  518. datacoll^.next:=propertyparas;
  519. propertyparas:=datacoll;
  520. pp:=get_procdef;
  521. { ... and remove it }
  522. propertyparas:=propertyparas^.next;
  523. if not(assigned(pp)) then
  524. Message(parser_e_ill_property_access_sym);
  525. p^.writeaccessdef:=pp;
  526. end
  527. else if sym^.typ=varsym then
  528. begin
  529. if not(is_equal(pvarsym(sym)^.definition,
  530. p^.proptype)) then
  531. Message(parser_e_ill_property_access_sym);
  532. end;
  533. p^.writeaccesssym:=sym;
  534. end;
  535. consume(ID);
  536. end;
  537. if (token=ID) and (pattern='STORED') then
  538. begin
  539. consume(ID);
  540. { !!!!!!!! }
  541. end;
  542. if (token=ID) and (pattern='DEFAULT') then
  543. begin
  544. consume(ID);
  545. { !!!!!!! storage }
  546. consume(SEMICOLON);
  547. end
  548. else if (token=ID) and (pattern='NODEFAULT') then
  549. begin
  550. consume(ID);
  551. { !!!!!!!! }
  552. end;
  553. symtablestack^.insert(p);
  554. { default property ? }
  555. consume(SEMICOLON);
  556. if (token=ID) and (pattern='DEFAULT') then
  557. begin
  558. consume(ID);
  559. p2:=search_default_property(aktclass);
  560. if assigned(p2) then
  561. message1(parser_e_only_one_default_property,
  562. pobjectdef(p2^.owner^.defowner)^.name^)
  563. else
  564. begin
  565. p^.options:=p^.options or ppo_defaultproperty;
  566. if not(assigned(propertyparas)) then
  567. message(parser_e_property_need_paras);
  568. end;
  569. consume(SEMICOLON);
  570. end;
  571. { clean up }
  572. if assigned(datacoll) then
  573. dispose(datacoll);
  574. end
  575. else
  576. begin
  577. consume(ID);
  578. consume(SEMICOLON);
  579. end;
  580. end;
  581. procedure destructor_head;
  582. begin
  583. consume(_DESTRUCTOR);
  584. _proc_head(podestructor);
  585. if (cs_checkconsname in aktswitches) and (aktprocsym^.name<>'DONE') then
  586. Message(parser_e_destructorname_must_be_done);
  587. consume(SEMICOLON);
  588. if assigned(aktprocsym^.definition^.para1) then
  589. Message(parser_e_no_paras_for_destructor);
  590. { no return value }
  591. aktprocsym^.definition^.retdef:=voiddef;
  592. end;
  593. procedure object_komponenten;
  594. var
  595. oldparse_only : boolean;
  596. begin
  597. repeat
  598. if actmembertype=sp_private then
  599. aktclass^.options:=aktclass^.options or oo_hasprivate;
  600. if actmembertype=sp_protected then
  601. aktclass^.options:=aktclass^.options or oo_hasprotected;
  602. case token of
  603. ID:
  604. begin
  605. if (pattern='PUBLIC') or
  606. (pattern='PUBLISHED') or
  607. (pattern='PROTECTED') or
  608. (pattern='PRIVATE') then
  609. exit;
  610. read_var_decs(false,false);
  611. end;
  612. _PROPERTY:
  613. property_dec;
  614. _PROCEDURE,_FUNCTION,_CLASS:
  615. begin
  616. oldparse_only:=parse_only;
  617. parse_only:=true;
  618. proc_head;
  619. parse_only:=oldparse_only;
  620. if (token=ID) and
  621. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  622. begin
  623. if actmembertype=sp_private then
  624. Message(parser_w_priv_meth_not_virtual);
  625. consume(ID);
  626. consume(SEMICOLON);
  627. aktprocsym^.definition^.options:=
  628. aktprocsym^.definition^.options or povirtualmethod;
  629. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  630. end
  631. else if (token=ID) and (pattern='OVERRIDE') then
  632. begin
  633. consume(ID);
  634. consume(SEMICOLON);
  635. aktprocsym^.definition^.options:=
  636. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  637. end;
  638. { Delphi II extension }
  639. if (token=ID) and (pattern='ABSTRACT') then
  640. begin
  641. consume(ID);
  642. consume(SEMICOLON);
  643. if (aktprocsym^.definition^.options and povirtualmethod)<>0 then
  644. begin
  645. aktprocsym^.definition^.options:=
  646. aktprocsym^.definition^.options or
  647. poabstractmethod;
  648. end
  649. else
  650. Message(parser_e_only_virtual_methods_abstract);
  651. { the method is defined }
  652. aktprocsym^.definition^.forwarddef:=false;
  653. end;
  654. if (token=ID) and (pattern='STATIC') and
  655. (cs_static_keyword in aktswitches) then
  656. begin
  657. consume(ID);
  658. consume(SEMICOLON);
  659. aktprocsym^.properties:=
  660. aktprocsym^.properties or
  661. sp_static;
  662. aktprocsym^.definition^.options:=
  663. aktprocsym^.definition^.options or
  664. postaticmethod;
  665. end;
  666. end;
  667. _CONSTRUCTOR:
  668. begin
  669. if actmembertype<>sp_public then
  670. Message(parser_w_constructor_should_be_public);
  671. oldparse_only:=parse_only;
  672. parse_only:=true;
  673. constructor_head;
  674. parse_only:=oldparse_only;
  675. if (token=ID) and
  676. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  677. begin
  678. consume(ID);
  679. consume(SEMICOLON);
  680. if not(aktclass^.isclass) then
  681. Message(parser_e_constructor_cannot_be_not_virtual)
  682. else
  683. begin
  684. aktprocsym^.definition^.options:=
  685. aktprocsym^.definition^.options or povirtualmethod;
  686. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  687. end
  688. end
  689. else if (token=ID) and (pattern='OVERRIDE') then
  690. begin
  691. consume(ID);
  692. consume(SEMICOLON);
  693. if (aktclass^.options and oois_class=0) then
  694. Message(parser_e_constructor_cannot_be_not_virtual)
  695. else
  696. begin
  697. aktprocsym^.definition^.options:=
  698. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  699. end;
  700. end;
  701. end;
  702. _DESTRUCTOR:
  703. begin
  704. if there_is_a_destructor then
  705. Message(parser_n_only_one_destructor);
  706. there_is_a_destructor:=true;
  707. if actmembertype<>sp_public then
  708. Message(parser_w_destructor_should_be_public);
  709. oldparse_only:=parse_only;
  710. parse_only:=true;
  711. destructor_head;
  712. parse_only:=oldparse_only;
  713. if (token=ID) and
  714. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  715. begin
  716. consume(ID);
  717. consume(SEMICOLON);
  718. aktprocsym^.definition^.options:=
  719. aktprocsym^.definition^.options or povirtualmethod;
  720. end
  721. else if (token=ID) and (pattern='OVERRIDE') then
  722. begin
  723. consume(ID);
  724. consume(SEMICOLON);
  725. aktprocsym^.definition^.options:=
  726. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  727. end;
  728. end;
  729. _END : exit;
  730. else Message(parser_e_syntax_error);
  731. end;
  732. until false;
  733. end;
  734. var
  735. hs : string;
  736. pcrd : pclassrefdef;
  737. hp1 : pdef;
  738. oldprocsym:Pprocsym;
  739. begin
  740. {Nowadays aktprocsym may already have a value, so we need to save
  741. it.}
  742. oldprocsym:=aktprocsym;
  743. { forward is resolved }
  744. if assigned(fd) then
  745. fd^.options:=fd^.options and not(oo_isforward);
  746. there_is_a_destructor:=false;
  747. actmembertype:=sp_public;
  748. { objects and class types can't be declared local }
  749. if (symtablestack^.symtabletype<>globalsymtable) and
  750. (symtablestack^.symtabletype<>staticsymtable) then
  751. Message(parser_e_no_local_objects);
  752. { distinguish classes and objects }
  753. if token=_OBJECT then
  754. begin
  755. is_a_class:=false;
  756. consume(_OBJECT)
  757. end
  758. else
  759. begin
  760. is_a_class:=true;
  761. consume(_CLASS);
  762. if not(assigned(fd)) and (token=_OF) then
  763. begin
  764. { a hack, but it's easy to handle }
  765. { class reference type }
  766. consume(_OF);
  767. if typecanbeforward then
  768. forwardsallowed:=true;
  769. hp1:=single_type(hs);
  770. { accept hp1, if is a forward def ...}
  771. if ((lasttypesym<>nil)
  772. and ((lasttypesym^.properties and sp_forwarddef)<>0)) or
  773. { or a class
  774. (if the foward defined type is a class is checked, when
  775. the forward is resolved)
  776. }
  777. ((hp1^.deftype=objectdef) and (
  778. (pobjectdef(hp1)^.options and oois_class)<>0)) then
  779. begin
  780. pcrd:=new(pclassrefdef,init(hp1));
  781. object_dec:=pcrd;
  782. {I add big troubles here
  783. with var p : ^byte in graph.putimage
  784. because a save_forward was called and
  785. no resolve forward
  786. => so the definition was rewritten after
  787. having been disposed !!
  788. Strange problems appeared !!!!}
  789. {Anyhow forwards should only be allowed
  790. inside a type statement ??
  791. don't you think so }
  792. if (lasttypesym<>nil)
  793. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  794. lasttypesym^.forwardpointer:=ppointerdef(pcrd);
  795. forwardsallowed:=false;
  796. end
  797. else
  798. begin
  799. Message(parser_e_class_type_expected);
  800. object_dec:=new(perrordef,init);
  801. end;
  802. exit;
  803. end
  804. { forward class }
  805. else if not(assigned(fd)) and (token=SEMICOLON) then
  806. begin
  807. { also anonym objects aren't allow (o : object a : longint; end;) }
  808. if n='' then
  809. Message(parser_e_no_anonym_objects);
  810. if n='TOBJECT' then
  811. begin
  812. aktclass:=new(pobjectdef,init(n,nil));
  813. class_tobject:=aktclass;
  814. end
  815. else
  816. aktclass:=new(pobjectdef,init(n,class_tobject));
  817. aktclass^.options:=aktclass^.options or oois_class or oo_isforward;
  818. object_dec:=aktclass;
  819. exit;
  820. end;
  821. end;
  822. { also anonym objects aren't allow (o : object a : longint; end;) }
  823. if n='' then
  824. Message(parser_e_no_anonym_objects);
  825. { read the parent class }
  826. if token=LKLAMMER then
  827. begin
  828. consume(LKLAMMER);
  829. { does not allow objects.tobject !! }
  830. {if token<>ID then
  831. consume(ID);
  832. getsym(pattern,true);}
  833. childof:=pobjectdef(id_type(pattern));
  834. if (childof^.deftype<>objectdef) then
  835. begin
  836. Message(parser_e_class_type_expected);
  837. childof:=nil;
  838. end;
  839. { a mix of class and object isn't allowed }
  840. if (((childof^.options and oois_class)<>0) and not is_a_class) or
  841. (((childof^.options and oois_class)=0) and is_a_class) then
  842. Message(parser_e_mix_of_classes_and_objects);
  843. consume(RKLAMMER);
  844. if assigned(fd) then
  845. begin
  846. fd^.childof:=childof;
  847. aktclass:=fd;
  848. end
  849. else
  850. aktclass:=new(pobjectdef,init(n,childof));
  851. end
  852. { if no parent class, then a class get tobject as parent }
  853. else if is_a_class then
  854. begin
  855. { is the current class tobject? }
  856. { so you could define your own tobject }
  857. if n='TOBJECT' then
  858. begin
  859. if assigned(fd) then
  860. aktclass:=fd
  861. else
  862. aktclass:=new(pobjectdef,init(n,nil));
  863. class_tobject:=aktclass;
  864. end
  865. else
  866. begin
  867. childof:=class_tobject;
  868. if assigned(fd) then
  869. begin
  870. aktclass:=fd;
  871. aktclass^.childof:=childof;
  872. end
  873. else
  874. aktclass:=new(pobjectdef,init(n,childof));
  875. end;
  876. end
  877. else aktclass:=new(pobjectdef,init(n,nil));
  878. { set the class attribute }
  879. if is_a_class then
  880. begin
  881. aktclass^.options:=aktclass^.options or oois_class;
  882. if (cs_generate_rtti in aktswitches) or
  883. (assigned(aktclass^.childof) and
  884. ((aktclass^.childof^.options and oo_can_have_published)<>0)
  885. ) then
  886. aktclass^.options:=aktclass^.options or oo_can_have_published;
  887. end;
  888. aktobjectdef:=aktclass;
  889. { default access is public }
  890. actmembertype:=sp_public;
  891. aktclass^.publicsyms^.next:=symtablestack;
  892. symtablestack:=aktclass^.publicsyms;
  893. procinfo._class:=aktclass;
  894. testcurobject:=1;
  895. curobjectname:=n;
  896. { short class declaration ? }
  897. if token<>SEMICOLON then
  898. begin
  899. while token<>_END do
  900. begin
  901. if (token=ID) and (pattern='PRIVATE') then
  902. begin
  903. consume(ID);
  904. actmembertype:=sp_private;
  905. current_object_option:=sp_private;
  906. end;
  907. if (token=ID) and (pattern='PROTECTED') then
  908. begin
  909. consume(ID);
  910. current_object_option:=sp_protected;
  911. actmembertype:=sp_protected;
  912. end;
  913. if (token=ID) and (pattern='PUBLIC') then
  914. begin
  915. consume(ID);
  916. current_object_option:=sp_public;
  917. actmembertype:=sp_public;
  918. end;
  919. if (token=ID) and (pattern='PUBLISHED') then
  920. begin
  921. if (aktclass^.options and oo_can_have_published)=0 then
  922. Message(parser_e_cant_have_published);
  923. consume(ID);
  924. current_object_option:=sp_published;
  925. actmembertype:=sp_published;
  926. end;
  927. object_komponenten;
  928. end;
  929. current_object_option:=sp_public;
  930. consume(_END);
  931. end;
  932. testcurobject:=0;
  933. curobjectname:='';
  934. if smartlink then
  935. datasegment^.concat(new(pai_cut,init));
  936. {$ifdef GDB}
  937. { generate the VMT }
  938. if cs_debuginfo in aktswitches then
  939. begin
  940. do_count_dbx:=true;
  941. if assigned(aktclass^.owner) and assigned(aktclass^.owner^.name) then
  942. datasegment^.concat(new(pai_stabs,init(strpnew('"vmt_'+aktclass^.owner^.name^+n+':S'+
  943. typeglobalnumber('__vtbl_ptr_type')+'",'+tostr(N_STSYM)+',0,0,'+aktclass^.vmt_mangledname))));
  944. end;
  945. {$endif * GDB *}
  946. datasegment^.concat(new(pai_symbol,init_global(aktclass^.vmt_mangledname)));
  947. { determine the size with publicsyms^.datasize, because }
  948. { size gives back 4 for CLASSes }
  949. datasegment^.concat(new(pai_const,init_32bit(aktclass^.publicsyms^.datasize)));
  950. datasegment^.concat(new(pai_const,init_32bit(-aktclass^.publicsyms^.datasize)));
  951. { write pointer to parent VMT, this isn't implemented in TP }
  952. { but this is not used in FPC ? (PM) }
  953. { it's not used yet, but the delphi-operators as and is need it (FK) }
  954. if assigned(aktclass^.childof) then
  955. begin
  956. datasegment^.concat(new(pai_const,init_symbol(strpnew(aktclass^.childof^.vmt_mangledname))));
  957. if aktclass^.childof^.owner^.symtabletype=unitsymtable then
  958. concat_external(aktclass^.childof^.vmt_mangledname,EXT_NEAR);
  959. end
  960. else
  961. datasegment^.concat(new(pai_const,init_32bit(0)));
  962. { this generates the entries }
  963. genvmt(aktclass);
  964. { restore old state }
  965. symtablestack:=symtablestack^.next;
  966. procinfo._class:=nil;
  967. {Restore the aktprocsym.}
  968. aktprocsym:=oldprocsym;
  969. object_dec:=aktclass;
  970. end;
  971. { reads a record declaration }
  972. function record_dec : pdef;
  973. var
  974. symtable : psymtable;
  975. begin
  976. symtable:=new(psymtable,init(recordsymtable));
  977. symtable^.next:=symtablestack;
  978. symtablestack:=symtable;
  979. consume(_RECORD);
  980. read_var_decs(true,false);
  981. { may be scale record size to a size of n*4 ? }
  982. if ((symtablestack^.datasize mod aktpackrecords)<>0) then
  983. inc(symtablestack^.datasize,aktpackrecords-(symtablestack^.datasize mod aktpackrecords));
  984. consume(_END);
  985. symtablestack:=symtable^.next;
  986. record_dec:=new(precdef,init(symtable));
  987. end;
  988. { reads a type definition and returns a pointer to it }
  989. function read_type(const name : stringid) : pdef;
  990. function handle_procvar:Pprocvardef;
  991. var
  992. sc : pstringcontainer;
  993. s : string;
  994. p : pdef;
  995. varspez : tvarspez;
  996. procvardef : pprocvardef;
  997. begin
  998. procvardef:=new(pprocvardef,init);
  999. if token=LKLAMMER then
  1000. begin
  1001. consume(LKLAMMER);
  1002. inc(testcurobject);
  1003. repeat
  1004. if token=_VAR then
  1005. begin
  1006. consume(_VAR);
  1007. varspez:=vs_var;
  1008. end
  1009. else if token=_CONST then
  1010. begin
  1011. consume(_CONST);
  1012. varspez:=vs_const;
  1013. end
  1014. else varspez:=vs_value;
  1015. sc:=idlist;
  1016. if token=COLON then
  1017. begin
  1018. consume(COLON);
  1019. if token=_ARRAY then
  1020. begin
  1021. {
  1022. if (varspez<>vs_const) and
  1023. (varspez<>vs_var) then
  1024. begin
  1025. varspez:=vs_const;
  1026. Message(parser_e_illegal_open_parameter);
  1027. end;
  1028. }
  1029. consume(_ARRAY);
  1030. consume(_OF);
  1031. { define range and type of range }
  1032. p:=new(parraydef,init(0,-1,s32bitdef));
  1033. { define field type }
  1034. parraydef(p)^.definition:=single_type(s);
  1035. end
  1036. else
  1037. p:=single_type(s);
  1038. end
  1039. else
  1040. p:=new(pformaldef,init);
  1041. s:=sc^.get;
  1042. while s<>'' do
  1043. begin
  1044. procvardef^.concatdef(p,varspez);
  1045. s:=sc^.get;
  1046. end;
  1047. dispose(sc,done);
  1048. if token=SEMICOLON then consume(SEMICOLON)
  1049. else break;
  1050. until false;
  1051. dec(testcurobject);
  1052. consume(RKLAMMER);
  1053. end;
  1054. handle_procvar:=procvardef;
  1055. end;
  1056. var
  1057. hp1,p : pdef;
  1058. aufdef : penumdef;
  1059. aufsym : penumsym;
  1060. ap : parraydef;
  1061. s : stringid;
  1062. l,v,oldaktpackrecords : longint;
  1063. hs : string;
  1064. procedure expr_type;
  1065. var
  1066. pt1,pt2 : ptree;
  1067. begin
  1068. { use of current parsed object ? }
  1069. if (token=ID) and (testcurobject=2) and (curobjectname=pattern) then
  1070. begin
  1071. consume(ID);
  1072. p:=aktobjectdef;
  1073. exit;
  1074. end;
  1075. { we can't accept a equal in type }
  1076. pt1:=comp_expr(not(ignore_equal));
  1077. if (pt1^.treetype=typen) and (token<>POINTPOINT) then
  1078. begin
  1079. { a simple type renaming }
  1080. p:=pt1^.resulttype;
  1081. end
  1082. else
  1083. begin
  1084. { range type }
  1085. consume(POINTPOINT);
  1086. { range type declaration }
  1087. do_firstpass(pt1);
  1088. pt2:=comp_expr(not(ignore_equal));
  1089. do_firstpass(pt2);
  1090. { valid expression ? }
  1091. if (pt1^.treetype<>ordconstn) or
  1092. (pt2^.treetype<>ordconstn) then
  1093. Begin
  1094. Message(sym_e_error_in_type_def);
  1095. { Here we create a node type with a range of 0 }
  1096. { To make sure that no crashes will occur later }
  1097. { on in the compiler. }
  1098. p:=new(porddef,init(uauto,0,0));
  1099. end
  1100. else
  1101. p:=new(porddef,init(uauto,pt1^.value,pt2^.value));
  1102. disposetree(pt2);
  1103. end;
  1104. disposetree(pt1);
  1105. end;
  1106. var
  1107. pt : ptree;
  1108. procedure array_dec;
  1109. begin
  1110. consume(_ARRAY);
  1111. consume(LECKKLAMMER);
  1112. p:=nil;
  1113. repeat
  1114. { read the expression and check it }
  1115. pt:=expr;
  1116. if pt^.treetype=typen then
  1117. begin
  1118. if pt^.resulttype^.deftype=enumdef then
  1119. begin
  1120. if p=nil then
  1121. begin
  1122. ap:=new(parraydef,
  1123. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1124. p:=ap;
  1125. end
  1126. else
  1127. begin
  1128. ap^.definition:=new(parraydef,
  1129. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1130. ap:=parraydef(ap^.definition);
  1131. end;
  1132. end
  1133. else if pt^.resulttype^.deftype=orddef then
  1134. begin
  1135. case porddef(pt^.resulttype)^.typ of
  1136. s8bit,u8bit,s16bit,u16bit,s32bit :
  1137. begin
  1138. if p=nil then
  1139. begin
  1140. ap:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1141. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1142. p:=ap;
  1143. end
  1144. else
  1145. begin
  1146. ap^.definition:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1147. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1148. ap:=parraydef(ap^.definition);
  1149. end;
  1150. end;
  1151. bool8bit:
  1152. begin
  1153. if p=nil then
  1154. begin
  1155. ap:=new(parraydef,init(0,1,pt^.resulttype));
  1156. p:=ap;
  1157. end
  1158. else
  1159. begin
  1160. ap^.definition:=new(parraydef,init(0,1,pt^.resulttype));
  1161. ap:=parraydef(ap^.definition);
  1162. end;
  1163. end;
  1164. uchar:
  1165. begin
  1166. if p=nil then
  1167. begin
  1168. ap:=new(parraydef,init(0,255,pt^.resulttype));
  1169. p:=ap;
  1170. end
  1171. else
  1172. begin
  1173. ap^.definition:=new(parraydef,init(0,255,pt^.resulttype));
  1174. ap:=parraydef(ap^.definition);
  1175. end;
  1176. end;
  1177. else Message(sym_e_error_in_type_def);
  1178. end;
  1179. end
  1180. else Message(sym_e_error_in_type_def);
  1181. end
  1182. else
  1183. begin
  1184. do_firstpass(pt);
  1185. if (pt^.treetype<>rangen) or
  1186. (pt^.left^.treetype<>ordconstn) then
  1187. Message(sym_e_error_in_type_def);
  1188. { force the registration of the ranges }
  1189. {$ifndef GDB}
  1190. if pt^.right^.resulttype=pdef(s32bitdef) then
  1191. pt^.right^.resulttype:=new(porddef,init(
  1192. s32bit,$80000000,$7fffffff));
  1193. {$endif GDB}
  1194. if p=nil then
  1195. begin
  1196. ap:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1197. p:=ap;
  1198. end
  1199. else
  1200. begin
  1201. ap^.definition:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1202. ap:=parraydef(ap^.definition);
  1203. end;
  1204. end;
  1205. disposetree(pt);
  1206. if token=COMMA then consume(COMMA)
  1207. else break;
  1208. until false;
  1209. consume(RECKKLAMMER);
  1210. consume(_OF);
  1211. hp1:=read_type('');
  1212. { if no error, set element type }
  1213. if assigned(ap) then
  1214. ap^.definition:=hp1;
  1215. end;
  1216. begin
  1217. case token of
  1218. _STRING,_FILE:
  1219. p:=single_type(hs);
  1220. LKLAMMER:
  1221. begin
  1222. consume(LKLAMMER);
  1223. l:=-1;
  1224. aufsym := Nil;
  1225. aufdef:=new(penumdef,init);
  1226. repeat
  1227. s:=pattern;
  1228. consume(ID);
  1229. if token=ASSIGNMENT then
  1230. begin
  1231. consume(ASSIGNMENT);
  1232. v:=get_intconst;
  1233. { please leave that a note, allows type save }
  1234. { declarations in the win32 units ! }
  1235. if v<=l then
  1236. Message(parser_n_duplicate_enum);
  1237. l:=v;
  1238. end
  1239. else
  1240. inc(l);
  1241. constsymtable^.insert(new(penumsym,init(s,aufdef,l)));
  1242. if token=COMMA then
  1243. consume(COMMA)
  1244. else
  1245. break;
  1246. until false;
  1247. aufdef^.max:=l;
  1248. p:=aufdef;
  1249. consume(RKLAMMER);
  1250. end;
  1251. _ARRAY:
  1252. array_dec;
  1253. _SET:
  1254. begin
  1255. consume(_SET);
  1256. consume(_OF);
  1257. hp1:=read_type('');
  1258. case hp1^.deftype of
  1259. enumdef : p:=new(psetdef,init(hp1,penumdef(hp1)^.max));
  1260. orddef : begin
  1261. case porddef(hp1)^.typ of
  1262. uchar : p:=new(psetdef,init(hp1,255));
  1263. u8bit,s8bit,u16bit,s16bit,s32bit :
  1264. begin
  1265. if (porddef(hp1)^.von>=0) then
  1266. p:=new(psetdef,init(hp1,porddef(hp1)^.bis))
  1267. else Message(sym_e_ill_type_decl_set);
  1268. end;
  1269. else Message(sym_e_ill_type_decl_set);
  1270. end;
  1271. end;
  1272. else Message(sym_e_ill_type_decl_set);
  1273. end;
  1274. end;
  1275. CARET:
  1276. begin
  1277. consume(CARET);
  1278. { forwards allowed only inside TYPE statements }
  1279. if typecanbeforward then
  1280. forwardsallowed:=true;
  1281. hp1:=single_type(hs);
  1282. p:=new(ppointerdef,init(hp1));
  1283. {$ifndef GDB}
  1284. if lasttypesym<>nil then
  1285. save_forward(ppointerdef(p),lasttypesym);
  1286. {$else * GDB *}
  1287. {I add big troubles here
  1288. with var p : ^byte in graph.putimage
  1289. because a save_forward was called and
  1290. no resolve forward
  1291. => so the definition was rewritten after
  1292. having been disposed !!
  1293. Strange problems appeared !!!!}
  1294. {Anyhow forwards should only be allowed
  1295. inside a type statement ??
  1296. don't you think so }
  1297. if (lasttypesym<>nil)
  1298. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  1299. lasttypesym^.forwardpointer:=ppointerdef(p);
  1300. {$endif * GDB *}
  1301. forwardsallowed:=false;
  1302. end;
  1303. _RECORD:
  1304. p:=record_dec;
  1305. _PACKED:
  1306. begin
  1307. consume(_PACKED);
  1308. if token=_ARRAY then
  1309. array_dec
  1310. else
  1311. begin
  1312. oldaktpackrecords:=aktpackrecords;
  1313. aktpackrecords:=1;
  1314. if token in [_CLASS,_OBJECT] then
  1315. p:=object_dec(name,nil)
  1316. else
  1317. p:=record_dec;
  1318. aktpackrecords:=oldaktpackrecords;
  1319. end;
  1320. end;
  1321. _CLASS,
  1322. _OBJECT:
  1323. p:=object_dec(name,nil);
  1324. _PROCEDURE:
  1325. begin
  1326. consume(_PROCEDURE);
  1327. p:=handle_procvar;
  1328. if token=_OF then
  1329. begin
  1330. consume(_OF);
  1331. consume(_OBJECT);
  1332. pprocvardef(p)^.options:=pprocvardef(p)^.options or pomethodpointer;
  1333. end;
  1334. end;
  1335. _FUNCTION:
  1336. begin
  1337. consume(_FUNCTION);
  1338. p:=handle_procvar;
  1339. consume(COLON);
  1340. pprocvardef(p)^.retdef:=single_type(hs);
  1341. if token=_OF then
  1342. begin
  1343. consume(_OF);
  1344. consume(_OBJECT);
  1345. pprocvardef(p)^.options:=pprocvardef(p)^.options or pomethodpointer;
  1346. end;
  1347. end;
  1348. else
  1349. expr_type;
  1350. end;
  1351. read_type:=p;
  1352. end;
  1353. { search in symtablestack used, but not defined type }
  1354. procedure testforward_types(p : psym);{$ifndef FPC}far;{$endif}
  1355. begin
  1356. if (p^.typ=typesym) and ((p^.properties and sp_forwarddef)<>0) then
  1357. Message(sym_e_type_id_not_defined);
  1358. end;
  1359. { reads a type declaration to the symbol table }
  1360. procedure type_dec;
  1361. var
  1362. typename : stringid;
  1363. {$ifdef dummy}
  1364. olddef,newdef : pdef;
  1365. s : string;
  1366. {$endif dummy}
  1367. begin
  1368. block_type:=bt_type;
  1369. consume(_TYPE);
  1370. typecanbeforward:=true;
  1371. repeat
  1372. typename:=pattern;
  1373. consume(ID);
  1374. consume(EQUAL);
  1375. { here you loose the strictness of pascal
  1376. for which a redefinition like
  1377. childtype = parenttype;
  1378. child2type = parenttype;
  1379. does not make the two child types equal !!
  1380. here all vars from childtype and child2type
  1381. get the definition of parenttype !! }
  1382. {$ifdef testequaltype}
  1383. if (token = ID) or (token=_FILE) or (token=_STRING) then
  1384. begin
  1385. olddef := single_type(s);
  1386. { make a clone of olddef }
  1387. { is that ok ??? }
  1388. getmem(newdef,SizeOf(olddef));
  1389. move(olddef^,newdef^,SizeOf(olddef));
  1390. symtablestack^.insert(new(ptypesym,init(typename,newdef)));
  1391. end
  1392. else
  1393. {$endif testequaltype}
  1394. begin
  1395. getsym(typename,false);
  1396. { check if it is the definition of a forward defined class }
  1397. if assigned(srsym) and (token=_CLASS) and
  1398. (srsym^.typ=typesym) and
  1399. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  1400. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oo_isforward)<>0) and
  1401. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oois_class)<>0) then
  1402. begin
  1403. { we can ignore the result }
  1404. { the definition is modified }
  1405. object_dec(typename,pobjectdef(ptypesym(srsym)^.definition));
  1406. end
  1407. else
  1408. symtablestack^.insert(new(ptypesym,init(typename,read_type(typename))));
  1409. end;
  1410. consume(SEMICOLON);
  1411. until token<>ID;
  1412. typecanbeforward:=false;
  1413. {$ifdef tp}
  1414. symtablestack^.foreach(testforward_types);
  1415. {$else}
  1416. symtablestack^.foreach(@testforward_types);
  1417. {$endif}
  1418. resolve_forwards;
  1419. block_type:=bt_general;
  1420. end;
  1421. { parses varaible declarations and inserts them in }
  1422. { the top symbol table of symtablestack }
  1423. procedure var_dec;
  1424. {var
  1425. p : pdef;
  1426. sc : pstringcontainer; }
  1427. begin
  1428. consume(_VAR);
  1429. read_var_decs(false,true);
  1430. end;
  1431. { reads the filed of a record into a }
  1432. { symtablestack, if record=false }
  1433. { variants are forbidden, so this procedure }
  1434. { can be used to read object fields }
  1435. { if absolute is true, ABSOLUTE and file }
  1436. { types are allowed }
  1437. { => the procedure is also used to read }
  1438. { a sequence of variable declaration }
  1439. procedure read_var_decs(is_record : boolean;do_absolute : boolean);
  1440. var
  1441. sc : pstringcontainer;
  1442. s : stringid;
  1443. l : longint;
  1444. code : word;
  1445. hs : string;
  1446. p,casedef : pdef;
  1447. { maxsize contains the max. size of a variant }
  1448. { startvarrec contains the start of the variant part of a record }
  1449. maxsize,startvarrec : longint;
  1450. pt : ptree;
  1451. old_block_type : tblock_type;
  1452. { to handle absolute }
  1453. abssym : pabsolutesym;
  1454. {$ifdef UseTokenInfo}
  1455. filepos : tfileposinfo;
  1456. {$endif UseTokenInfo}
  1457. begin
  1458. hs:='';
  1459. old_block_type:=block_type;
  1460. block_type:=bt_type;
  1461. while (token=ID) and
  1462. (pattern<>'PUBLIC') and
  1463. (pattern<>'PRIVATE') and
  1464. (pattern<>'PUBLISHED') and
  1465. (pattern<>'PROTECTED') do
  1466. begin
  1467. sc:=idlist;
  1468. consume(COLON);
  1469. p:=read_type('');
  1470. if do_absolute and (token=ID) and (pattern='ABSOLUTE') then
  1471. begin
  1472. {$ifdef UseTokenInfo}
  1473. s:=sc^.get_with_tokeninfo(filepos);
  1474. {$else UseTokenInfo}
  1475. s:=sc^.get;
  1476. {$endif UseTokenInfo}
  1477. if sc^.get<>'' then
  1478. Message(parser_e_absolute_only_one_var);
  1479. dispose(sc,done);
  1480. consume(ID);
  1481. if token=ID then
  1482. begin
  1483. getsym(pattern,true);
  1484. consume(ID);
  1485. { we should check the result type of srsym }
  1486. if not (srsym^.typ in [varsym,typedconstsym]) then
  1487. Message(parser_e_absolute_only_to_var_or_const);
  1488. abssym:=new(pabsolutesym,init(s,p));
  1489. abssym^.typ:=absolutesym;
  1490. abssym^.abstyp:=tovar;
  1491. abssym^.ref:=srsym;
  1492. {$ifdef UseTokenInfo}
  1493. abssym^.line_no:=filepos.line;
  1494. {$endif UseTokenInfo}
  1495. symtablestack^.insert(abssym);
  1496. end
  1497. else
  1498. if token=CSTRING then
  1499. begin
  1500. abssym:=new(pabsolutesym,init(s,p));
  1501. s:=pattern;
  1502. consume(CSTRING);
  1503. abssym^.typ:=absolutesym;
  1504. abssym^.abstyp:=toasm;
  1505. abssym^.asmname:=stringdup(s);
  1506. {$ifdef UseTokenInfo}
  1507. abssym^.line_no:=filepos.line;
  1508. {$endif UseTokenInfo}
  1509. symtablestack^.insert(abssym);
  1510. end
  1511. else
  1512. { absolute address ?!? }
  1513. if token=INTCONST then
  1514. begin
  1515. if (target_info.target=target_GO32V2) then
  1516. begin
  1517. abssym:=new(pabsolutesym,init(s,p));
  1518. abssym^.typ:=absolutesym;
  1519. abssym^.abstyp:=toaddr;
  1520. abssym^.absseg:=false;
  1521. {$ifdef UseTokenInfo}
  1522. abssym^.line_no:=filepos.line;
  1523. {$endif UseTokenInfo}
  1524. s:=pattern;
  1525. consume(INTCONST);
  1526. val(s,abssym^.address,code);
  1527. if token=COLON then
  1528. begin
  1529. consume(token);
  1530. s:=pattern;
  1531. consume(INTCONST);
  1532. val(s,l,code);
  1533. abssym^.address:=abssym^.address shl 4+l;
  1534. abssym^.absseg:=true;
  1535. end;
  1536. symtablestack^.insert(abssym);
  1537. end
  1538. else
  1539. Message(parser_e_absolute_only_to_var_or_const);
  1540. end
  1541. else
  1542. Message(parser_e_absolute_only_to_var_or_const);
  1543. end
  1544. else
  1545. begin
  1546. if token=SEMICOLON then
  1547. begin
  1548. if (symtablestack^.symtabletype=objectsymtable) then
  1549. begin
  1550. consume(SEMICOLON);
  1551. if (token=ID) and (pattern='STATIC') and
  1552. (cs_static_keyword in aktswitches) then
  1553. begin
  1554. current_object_option:=current_object_option or sp_static;
  1555. insert_syms(symtablestack,sc,p);
  1556. current_object_option:=current_object_option - sp_static;
  1557. consume(ID);
  1558. consume(SEMICOLON);
  1559. end
  1560. else
  1561. { this will still be a the wrong line !! }
  1562. insert_syms(symtablestack,sc,p);
  1563. end
  1564. else
  1565. begin
  1566. { at the right line }
  1567. insert_syms(symtablestack,sc,p);
  1568. consume(SEMICOLON);
  1569. end
  1570. end
  1571. else
  1572. begin
  1573. insert_syms(symtablestack,sc,p);
  1574. if not(is_record) then
  1575. consume(SEMICOLON);
  1576. end;
  1577. end;
  1578. while token=SEMICOLON do
  1579. consume(SEMICOLON);
  1580. end;
  1581. if (token=_CASE) and is_record then
  1582. begin
  1583. maxsize:=0;
  1584. consume(_CASE);
  1585. s:=pattern;
  1586. getsym(s,false);
  1587. { may be only a type: }
  1588. if assigned(srsym) and ((srsym^.typ=typesym) or
  1589. { and with unit qualifier: }
  1590. (srsym^.typ=unitsym)) then
  1591. begin
  1592. casedef:=read_type('');
  1593. end
  1594. else
  1595. begin
  1596. consume(ID);
  1597. consume(COLON);
  1598. casedef:=read_type('');
  1599. symtablestack^.insert(new(pvarsym,init(s,casedef)));
  1600. end;
  1601. if not is_ordinal(casedef) then
  1602. Message(parser_e_ordinal_expected);
  1603. consume(_OF);
  1604. startvarrec:=symtablestack^.datasize;
  1605. repeat
  1606. repeat
  1607. pt:=comp_expr(true);
  1608. do_firstpass(pt);
  1609. if not(pt^.treetype=ordconstn) then
  1610. Message(cg_e_illegal_expression);
  1611. disposetree(pt);
  1612. if token=COMMA then consume(COMMA)
  1613. else break;
  1614. until false;
  1615. consume(COLON);
  1616. consume(LKLAMMER);
  1617. if token<>RKLAMMER then
  1618. read_var_decs(true,false);
  1619. { calculates maximal variant size }
  1620. maxsize:=max(maxsize,symtablestack^.datasize);
  1621. { the items of the next variant are overlayed }
  1622. symtablestack^.datasize:=startvarrec;
  1623. consume(RKLAMMER);
  1624. if token<>SEMICOLON then
  1625. break
  1626. else
  1627. consume(SEMICOLON);
  1628. while token=SEMICOLON do
  1629. consume(SEMICOLON);
  1630. until (token=_END) or (token=RKLAMMER);
  1631. { at last set the record size to that of the biggest variant }
  1632. symtablestack^.datasize:=maxsize;
  1633. end;
  1634. block_type:=old_block_type;
  1635. end;
  1636. procedure read_declarations(islibrary : boolean);
  1637. begin
  1638. repeat
  1639. case token of
  1640. _LABEL:
  1641. label_dec;
  1642. _CONST:
  1643. const_dec;
  1644. _TYPE:
  1645. type_dec;
  1646. _VAR:
  1647. var_dec;
  1648. _CONSTRUCTOR,_DESTRUCTOR,
  1649. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1650. unter_dec;
  1651. _EXPORTS:
  1652. if islibrary then
  1653. read_exports
  1654. else
  1655. break;
  1656. else break;
  1657. end;
  1658. until false;
  1659. end;
  1660. procedure read_interface_declarations;
  1661. begin
  1662. {Since the body is now parsed at lexlevel 1, and the declarations
  1663. must be parsed at the same lexlevel we increase the lexlevel.}
  1664. inc(lexlevel);
  1665. repeat
  1666. case token of
  1667. _CONST : const_dec;
  1668. _TYPE : type_dec;
  1669. _VAR : var_dec;
  1670. { should we allow operator in interface ? }
  1671. { of course otherwise you cannot }
  1672. { declare an operator usable by other }
  1673. { units or progs PM }
  1674. _FUNCTION,_PROCEDURE,_OPERATOR : unter_dec;
  1675. else
  1676. break;
  1677. end;
  1678. until false;
  1679. dec(lexlevel);
  1680. end;
  1681. end.
  1682. {
  1683. $Log$
  1684. Revision 1.16 1998-05-05 12:05:42 florian
  1685. * problems with properties fixed
  1686. * crash fixed: i:=l when i and l are undefined, was a problem with
  1687. implementation of private/protected
  1688. Revision 1.15 1998/05/01 09:01:23 florian
  1689. + correct semantics of private and protected
  1690. * small fix in variable scope:
  1691. a id can be used in a parameter list of a method, even it is used in
  1692. an anchestor class as field id
  1693. Revision 1.14 1998/05/01 07:43:56 florian
  1694. + basics for rtti implemented
  1695. + switch $m (generate rtti for published sections)
  1696. Revision 1.13 1998/04/30 15:59:41 pierre
  1697. * GDB works again better :
  1698. correct type info in one pass
  1699. + UseTokenInfo for better source position
  1700. * fixed one remaining bug in scanner for line counts
  1701. * several little fixes
  1702. Revision 1.12 1998/04/29 10:33:57 pierre
  1703. + added some code for ansistring (not complete nor working yet)
  1704. * corrected operator overloading
  1705. * corrected nasm output
  1706. + started inline procedures
  1707. + added starstarn : use ** for exponentiation (^ gave problems)
  1708. + started UseTokenInfo cond to get accurate positions
  1709. Revision 1.11 1998/04/28 11:45:52 florian
  1710. * make it compilable with TP
  1711. + small COM problems solved to compile classes.pp
  1712. Revision 1.10 1998/04/27 23:10:28 peter
  1713. + new scanner
  1714. * $makelib -> if smartlink
  1715. * small filename fixes pmodule.setfilename
  1716. * moved import from files.pas -> import.pas
  1717. Revision 1.9 1998/04/10 21:36:56 florian
  1718. + some stuff to support method pointers (procedure of object) added
  1719. (declaration, parameter handling)
  1720. Revision 1.8 1998/04/10 15:39:48 florian
  1721. * more fixes to get classes.pas compiled
  1722. Revision 1.7 1998/04/09 23:02:15 florian
  1723. * small problems solved to get remake3 work
  1724. Revision 1.6 1998/04/09 22:16:35 florian
  1725. * problem with previous REGALLOC solved
  1726. * improved property support
  1727. Revision 1.5 1998/04/08 14:59:20 florian
  1728. * problem with new expr_type solved
  1729. Revision 1.4 1998/04/08 10:26:09 florian
  1730. * correct error handling of virtual constructors
  1731. * problem with new type declaration handling fixed
  1732. Revision 1.3 1998/04/07 22:45:05 florian
  1733. * bug0092, bug0115 and bug0121 fixed
  1734. + packed object/class/array
  1735. Revision 1.2 1998/04/05 13:58:35 peter
  1736. * fixed the -Ss bug
  1737. + warning for Virtual constructors
  1738. * helppages updated with -TGO32V1
  1739. Revision 1.1.1.1 1998/03/25 11:18:14 root
  1740. * Restored version
  1741. Revision 1.31 1998/03/24 21:48:33 florian
  1742. * just a couple of fixes applied:
  1743. - problem with fixed16 solved
  1744. - internalerror 10005 problem fixed
  1745. - patch for assembler reading
  1746. - small optimizer fix
  1747. - mem is now supported
  1748. Revision 1.30 1998/03/21 23:59:39 florian
  1749. * indexed properties fixed
  1750. * ppu i/o of properties fixed
  1751. * field can be also used for write access
  1752. * overriding of properties
  1753. Revision 1.29 1998/03/18 22:50:11 florian
  1754. + fstp/fld optimization
  1755. * routines which contains asm aren't longer optimzed
  1756. * wrong ifdef TEST_FUNCRET corrected
  1757. * wrong data generation for array[0..n] of char = '01234'; fixed
  1758. * bug0097 is fixed partial
  1759. * bug0116 fixed (-Og doesn't use enter of the stack frame is greater than
  1760. 65535)
  1761. Revision 1.28 1998/03/10 16:27:41 pierre
  1762. * better line info in stabs debug
  1763. * symtabletype and lexlevel separated into two fields of tsymtable
  1764. + ifdef MAKELIB for direct library output, not complete
  1765. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1766. working
  1767. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1768. working
  1769. Revision 1.27 1998/03/10 01:17:23 peter
  1770. * all files have the same header
  1771. * messages are fully implemented, EXTDEBUG uses Comment()
  1772. + AG... files for the Assembler generation
  1773. Revision 1.26 1998/03/06 00:52:41 peter
  1774. * replaced all old messages from errore.msg, only ExtDebug and some
  1775. Comment() calls are left
  1776. * fixed options.pas
  1777. Revision 1.25 1998/03/05 22:43:49 florian
  1778. * some win32 support stuff added
  1779. Revision 1.24 1998/03/04 17:33:49 michael
  1780. + Changed ifdef FPK to ifdef FPC
  1781. Revision 1.23 1998/03/04 01:35:06 peter
  1782. * messages for unit-handling and assembler/linker
  1783. * the compiler compiles without -dGDB, but doesn't work yet
  1784. + -vh for Hint
  1785. Revision 1.22 1998/03/02 01:49:00 peter
  1786. * renamed target_DOS to target_GO32V1
  1787. + new verbose system, merged old errors and verbose units into one new
  1788. verbose.pas, so errors.pas is obsolete
  1789. Revision 1.21 1998/02/28 14:43:47 florian
  1790. * final implemenation of win32 imports
  1791. * extended tai_align to allow 8 and 16 byte aligns
  1792. Revision 1.20 1998/02/19 00:11:07 peter
  1793. * fixed -g to work again
  1794. * fixed some typos with the scriptobject
  1795. Revision 1.19 1998/02/13 10:35:23 daniel
  1796. * Made Motorola version compilable.
  1797. * Fixed optimizer
  1798. Revision 1.18 1998/02/12 17:19:19 florian
  1799. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1800. also that aktswitches isn't a pointer)
  1801. Revision 1.17 1998/02/12 11:50:25 daniel
  1802. Yes! Finally! After three retries, my patch!
  1803. Changes:
  1804. Complete rewrite of psub.pas.
  1805. Added support for DLL's.
  1806. Compiler requires less memory.
  1807. Platform units for each platform.
  1808. Revision 1.16 1998/02/11 21:56:36 florian
  1809. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  1810. Revision 1.15 1998/02/06 10:34:25 florian
  1811. * bug0082 and bug0084 fixed
  1812. Revision 1.14 1998/02/02 11:56:49 pierre
  1813. * better line info for var statement
  1814. Revision 1.13 1998/01/30 21:25:31 carl
  1815. * bugfix #86 + checking of all other macros for crashes, fixed typeof
  1816. partly among others.
  1817. Revision 1.12 1998/01/23 17:12:19 pierre
  1818. * added some improvements for as and ld :
  1819. - doserror and dosexitcode treated separately
  1820. - PATH searched if doserror=2
  1821. + start of long and ansi string (far from complete)
  1822. in conditionnal UseLongString and UseAnsiString
  1823. * options.pas cleaned (some variables shifted to globals)gl
  1824. Revision 1.11 1998/01/21 21:25:46 florian
  1825. * small problem with variante records fixed:
  1826. case a : (x,y,z) of
  1827. ...
  1828. is now allowed
  1829. Revision 1.10 1998/01/13 23:11:13 florian
  1830. + class methods
  1831. Revision 1.9 1998/01/12 13:03:31 florian
  1832. + parsing of class methods implemented
  1833. Revision 1.8 1998/01/11 10:54:23 florian
  1834. + generic library support
  1835. Revision 1.7 1998/01/09 23:08:32 florian
  1836. + C++/Delphi styled //-comments
  1837. * some bugs in Delphi object model fixed
  1838. + override directive
  1839. Revision 1.6 1998/01/09 18:01:16 florian
  1840. * VIRTUAL isn't anymore a common keyword
  1841. + DYNAMIC is equal to VIRTUAL
  1842. Revision 1.5 1998/01/09 16:08:23 florian
  1843. * abstract methods call now abstracterrorproc if they are called
  1844. a class with an abstract method can be create with a class reference else
  1845. the compiler forbides this
  1846. Revision 1.4 1998/01/09 13:39:55 florian
  1847. * public, protected and private aren't anymore key words
  1848. + published is equal to public
  1849. Revision 1.3 1998/01/09 13:18:12 florian
  1850. + "forward" class declarations (type tclass = class; )
  1851. Revision 1.2 1998/01/09 09:09:58 michael
  1852. + Initial implementation, second try
  1853. }