pdecl.pas 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983
  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:=expr;
  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:=expr;
  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. case token of
  599. ID:
  600. begin
  601. if (pattern='PUBLIC') or
  602. (pattern='PUBLISHED') or
  603. (pattern='PROTECTED') or
  604. (pattern='PRIVATE') then
  605. exit;
  606. read_var_decs(false,false);
  607. end;
  608. _PROPERTY:
  609. property_dec;
  610. _PROCEDURE,_FUNCTION,_CLASS:
  611. begin
  612. oldparse_only:=parse_only;
  613. parse_only:=true;
  614. proc_head;
  615. parse_only:=oldparse_only;
  616. if (token=ID) and
  617. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  618. begin
  619. if actmembertype=sp_private then
  620. Message(parser_w_priv_meth_not_virtual);
  621. consume(ID);
  622. consume(SEMICOLON);
  623. aktprocsym^.definition^.options:=
  624. aktprocsym^.definition^.options or povirtualmethod;
  625. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  626. end
  627. else if (token=ID) and (pattern='OVERRIDE') then
  628. begin
  629. consume(ID);
  630. consume(SEMICOLON);
  631. aktprocsym^.definition^.options:=
  632. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  633. end;
  634. { Delphi II extension }
  635. if (token=ID) and (pattern='ABSTRACT') then
  636. begin
  637. consume(ID);
  638. consume(SEMICOLON);
  639. if (aktprocsym^.definition^.options and povirtualmethod)<>0 then
  640. begin
  641. aktprocsym^.definition^.options:=
  642. aktprocsym^.definition^.options or
  643. poabstractmethod;
  644. end
  645. else
  646. Message(parser_e_only_virtual_methods_abstract);
  647. { the method is defined }
  648. aktprocsym^.definition^.forwarddef:=false;
  649. end;
  650. if (token=ID) and (pattern='STATIC') and
  651. (cs_static_keyword in aktswitches) then
  652. begin
  653. consume(ID);
  654. consume(SEMICOLON);
  655. aktprocsym^.properties:=
  656. aktprocsym^.properties or
  657. sp_static;
  658. aktprocsym^.definition^.options:=
  659. aktprocsym^.definition^.options or
  660. postaticmethod;
  661. end;
  662. end;
  663. _CONSTRUCTOR:
  664. begin
  665. if actmembertype<>sp_public then
  666. Message(parser_e_constructor_cannot_be_private);
  667. oldparse_only:=parse_only;
  668. parse_only:=true;
  669. constructor_head;
  670. parse_only:=oldparse_only;
  671. if (token=ID) and
  672. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  673. begin
  674. consume(ID);
  675. consume(SEMICOLON);
  676. if not(aktclass^.isclass) then
  677. Message(parser_e_constructor_cannot_be_not_virtual)
  678. else
  679. begin
  680. aktprocsym^.definition^.options:=
  681. aktprocsym^.definition^.options or povirtualmethod;
  682. aktclass^.options:=aktclass^.options or oo_hasvirtual;
  683. end
  684. end
  685. else if (token=ID) and (pattern='OVERRIDE') then
  686. begin
  687. consume(ID);
  688. consume(SEMICOLON);
  689. if (aktclass^.options and oois_class=0) then
  690. Message(parser_e_constructor_cannot_be_not_virtual)
  691. else
  692. begin
  693. aktprocsym^.definition^.options:=
  694. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  695. end;
  696. end;
  697. end;
  698. _DESTRUCTOR:
  699. begin
  700. if there_is_a_destructor then
  701. Message(parser_n_only_one_destructor);
  702. there_is_a_destructor:=true;
  703. if actmembertype<>sp_public then
  704. Message(parser_e_destructor_cannot_be_private);
  705. oldparse_only:=parse_only;
  706. parse_only:=true;
  707. destructor_head;
  708. parse_only:=oldparse_only;
  709. if (token=ID) and
  710. ((pattern='VIRTUAL') or (pattern='DYNAMIC')) then
  711. begin
  712. consume(ID);
  713. consume(SEMICOLON);
  714. aktprocsym^.definition^.options:=
  715. aktprocsym^.definition^.options or povirtualmethod;
  716. end
  717. else if (token=ID) and (pattern='OVERRIDE') then
  718. begin
  719. consume(ID);
  720. consume(SEMICOLON);
  721. aktprocsym^.definition^.options:=
  722. aktprocsym^.definition^.options or pooverridingmethod or povirtualmethod;
  723. end;
  724. end;
  725. _END : exit;
  726. else Message(parser_e_syntax_error);
  727. end;
  728. until false;
  729. end;
  730. var
  731. hs : string;
  732. pcrd : pclassrefdef;
  733. hp1 : pdef;
  734. oldprocsym:Pprocsym;
  735. begin
  736. {Nowadays aktprocsym may already have a value, so we need to save
  737. it.}
  738. oldprocsym:=aktprocsym;
  739. { forward is resolved }
  740. if assigned(fd) then
  741. fd^.options:=fd^.options and not(oo_isforward);
  742. there_is_a_destructor:=false;
  743. actmembertype:=sp_public;
  744. { objects and class types can't be declared local }
  745. if (symtablestack^.symtabletype<>globalsymtable) and
  746. (symtablestack^.symtabletype<>staticsymtable) then
  747. Message(parser_e_no_local_objects);
  748. { distinguish classes and objects }
  749. if token=_OBJECT then
  750. begin
  751. is_a_class:=false;
  752. consume(_OBJECT)
  753. end
  754. else
  755. begin
  756. is_a_class:=true;
  757. consume(_CLASS);
  758. if not(assigned(fd)) and (token=_OF) then
  759. begin
  760. { a hack, but it's easy to handle }
  761. { class reference type }
  762. consume(_OF);
  763. if typecanbeforward then
  764. forwardsallowed:=true;
  765. hp1:=single_type(hs);
  766. { accept hp1, if is a forward def ...}
  767. if ((lasttypesym<>nil)
  768. and ((lasttypesym^.properties and sp_forwarddef)<>0)) or
  769. { or a class
  770. (if the foward defined type is a class is checked, when
  771. the forward is resolved)
  772. }
  773. ((hp1^.deftype=objectdef) and (
  774. (pobjectdef(hp1)^.options and oois_class)<>0)) then
  775. begin
  776. pcrd:=new(pclassrefdef,init(hp1));
  777. object_dec:=pcrd;
  778. {I add big troubles here
  779. with var p : ^byte in graph.putimage
  780. because a save_forward was called and
  781. no resolve forward
  782. => so the definition was rewritten after
  783. having been disposed !!
  784. Strange problems appeared !!!!}
  785. {Anyhow forwards should only be allowed
  786. inside a type statement ??
  787. don't you think so }
  788. if (lasttypesym<>nil)
  789. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  790. lasttypesym^.forwardpointer:=ppointerdef(pcrd);
  791. forwardsallowed:=false;
  792. end
  793. else
  794. begin
  795. Message(parser_e_class_type_expected);
  796. object_dec:=new(perrordef,init);
  797. end;
  798. exit;
  799. end
  800. { forward class }
  801. else if not(assigned(fd)) and (token=SEMICOLON) then
  802. begin
  803. { also anonym objects aren't allow (o : object a : longint; end;) }
  804. if n='' then
  805. Message(parser_e_no_anonym_objects);
  806. if n='TOBJECT' then
  807. begin
  808. aktclass:=new(pobjectdef,init(n,nil));
  809. class_tobject:=aktclass;
  810. end
  811. else
  812. aktclass:=new(pobjectdef,init(n,class_tobject));
  813. aktclass^.options:=aktclass^.options or oois_class or oo_isforward;
  814. object_dec:=aktclass;
  815. exit;
  816. end;
  817. end;
  818. { also anonym objects aren't allow (o : object a : longint; end;) }
  819. if n='' then
  820. Message(parser_e_no_anonym_objects);
  821. { read the parent class }
  822. if token=LKLAMMER then
  823. begin
  824. consume(LKLAMMER);
  825. { does not allow objects.tobject !! }
  826. {if token<>ID then
  827. consume(ID);
  828. getsym(pattern,true);}
  829. childof:=pobjectdef(id_type(pattern));
  830. if (childof^.deftype<>objectdef) then
  831. begin
  832. Message(parser_e_class_type_expected);
  833. childof:=nil;
  834. end;
  835. { a mix of class and object isn't allowed }
  836. if (((childof^.options and oois_class)<>0) and not is_a_class) or
  837. (((childof^.options and oois_class)=0) and is_a_class) then
  838. Message(parser_e_mix_of_classes_and_objects);
  839. consume(RKLAMMER);
  840. if assigned(fd) then
  841. begin
  842. fd^.childof:=childof;
  843. aktclass:=fd;
  844. end
  845. else
  846. aktclass:=new(pobjectdef,init(n,childof));
  847. end
  848. { if no parent class, then a class get tobject as parent }
  849. else if is_a_class then
  850. begin
  851. { is the current class tobject? }
  852. { so you could define your own tobject }
  853. if n='TOBJECT' then
  854. begin
  855. if assigned(fd) then
  856. aktclass:=fd
  857. else
  858. aktclass:=new(pobjectdef,init(n,nil));
  859. class_tobject:=aktclass;
  860. end
  861. else
  862. begin
  863. childof:=class_tobject;
  864. if assigned(fd) then
  865. begin
  866. aktclass:=fd;
  867. aktclass^.childof:=childof;
  868. end
  869. else
  870. aktclass:=new(pobjectdef,init(n,childof));
  871. end;
  872. end
  873. else aktclass:=new(pobjectdef,init(n,nil));
  874. { set the class attribute }
  875. if is_a_class then
  876. aktclass^.options:=aktclass^.options or oois_class;
  877. aktobjectdef:=aktclass;
  878. { default access is public }
  879. actmembertype:=sp_public;
  880. aktclass^.publicsyms^.next:=symtablestack;
  881. symtablestack:=aktclass^.publicsyms;
  882. procinfo._class:=aktclass;
  883. testcurobject:=1;
  884. curobjectname:=n;
  885. { short class declaration ? }
  886. if token<>SEMICOLON then
  887. begin
  888. while token<>_END do
  889. begin
  890. if (token=ID) and (pattern='PRIVATE') then
  891. begin
  892. consume(ID);
  893. actmembertype:=sp_private;
  894. current_object_option:=sp_private;
  895. end;
  896. if (token=ID) and (pattern='PROTECTED') then
  897. begin
  898. consume(ID);
  899. current_object_option:=sp_protected;
  900. actmembertype:=sp_protected;
  901. end;
  902. if (token=ID) and (pattern='PUBLIC') then
  903. begin
  904. consume(ID);
  905. current_object_option:=sp_public;
  906. actmembertype:=sp_public;
  907. end;
  908. if (token=ID) and (pattern='PUBLISHED') then
  909. begin
  910. consume(ID);
  911. current_object_option:=sp_public;
  912. actmembertype:=sp_public;
  913. end;
  914. object_komponenten;
  915. end;
  916. current_object_option:=sp_public;
  917. consume(_END);
  918. end;
  919. testcurobject:=0;
  920. curobjectname:='';
  921. if smartlink then
  922. datasegment^.concat(new(pai_cut,init));
  923. {$ifdef GDB}
  924. { generate the VMT }
  925. if cs_debuginfo in aktswitches then
  926. begin
  927. do_count_dbx:=true;
  928. if assigned(aktclass^.owner) and assigned(aktclass^.owner^.name) then
  929. datasegment^.concat(new(pai_stabs,init(strpnew('"vmt_'+aktclass^.owner^.name^+n+':S'+
  930. typeglobalnumber('__vtbl_ptr_type')+'",'+tostr(N_STSYM)+',0,0,'+aktclass^.vmt_mangledname))));
  931. end;
  932. {$endif * GDB *}
  933. datasegment^.concat(new(pai_symbol,init_global(aktclass^.vmt_mangledname)));
  934. { determine the size with publicsyms^.datasize, because }
  935. { size gives back 4 for CLASSes }
  936. datasegment^.concat(new(pai_const,init_32bit(aktclass^.publicsyms^.datasize)));
  937. datasegment^.concat(new(pai_const,init_32bit(-aktclass^.publicsyms^.datasize)));
  938. { write pointer to parent VMT, this isn't implemented in TP }
  939. { but this is not used in FPC ? (PM) }
  940. { it's not used yet, but the delphi-operators as and is need it (FK) }
  941. if assigned(aktclass^.childof) then
  942. begin
  943. datasegment^.concat(new(pai_const,init_symbol(strpnew(aktclass^.childof^.vmt_mangledname))));
  944. if aktclass^.childof^.owner^.symtabletype=unitsymtable then
  945. concat_external(aktclass^.childof^.vmt_mangledname,EXT_NEAR);
  946. end
  947. else
  948. datasegment^.concat(new(pai_const,init_32bit(0)));
  949. { this generates the entries }
  950. genvmt(aktclass);
  951. { restore old state }
  952. symtablestack:=symtablestack^.next;
  953. procinfo._class:=nil;
  954. {Restore the aktprocsym.}
  955. aktprocsym:=oldprocsym;
  956. object_dec:=aktclass;
  957. end;
  958. { reads a record declaration }
  959. function record_dec : pdef;
  960. var
  961. symtable : psymtable;
  962. begin
  963. symtable:=new(psymtable,init(recordsymtable));
  964. symtable^.next:=symtablestack;
  965. symtablestack:=symtable;
  966. consume(_RECORD);
  967. read_var_decs(true,false);
  968. { may be scale record size to a size of n*4 ? }
  969. if ((symtablestack^.datasize mod aktpackrecords)<>0) then
  970. inc(symtablestack^.datasize,aktpackrecords-(symtablestack^.datasize mod aktpackrecords));
  971. consume(_END);
  972. symtablestack:=symtable^.next;
  973. record_dec:=new(precdef,init(symtable));
  974. end;
  975. { reads a type definition and returns a pointer to it }
  976. function read_type(const name : stringid) : pdef;
  977. function handle_procvar:Pprocvardef;
  978. var
  979. sc : pstringcontainer;
  980. s : string;
  981. p : pdef;
  982. varspez : tvarspez;
  983. procvardef : pprocvardef;
  984. begin
  985. procvardef:=new(pprocvardef,init);
  986. if token=LKLAMMER then
  987. begin
  988. consume(LKLAMMER);
  989. inc(testcurobject);
  990. repeat
  991. if token=_VAR then
  992. begin
  993. consume(_VAR);
  994. varspez:=vs_var;
  995. end
  996. else if token=_CONST then
  997. begin
  998. consume(_CONST);
  999. varspez:=vs_const;
  1000. end
  1001. else varspez:=vs_value;
  1002. sc:=idlist;
  1003. if token=COLON then
  1004. begin
  1005. consume(COLON);
  1006. if token=_ARRAY then
  1007. begin
  1008. {
  1009. if (varspez<>vs_const) and
  1010. (varspez<>vs_var) then
  1011. begin
  1012. varspez:=vs_const;
  1013. Message(parser_e_illegal_open_parameter);
  1014. end;
  1015. }
  1016. consume(_ARRAY);
  1017. consume(_OF);
  1018. { define range and type of range }
  1019. p:=new(parraydef,init(0,-1,s32bitdef));
  1020. { define field type }
  1021. parraydef(p)^.definition:=single_type(s);
  1022. end
  1023. else
  1024. p:=single_type(s);
  1025. end
  1026. else
  1027. p:=new(pformaldef,init);
  1028. s:=sc^.get;
  1029. while s<>'' do
  1030. begin
  1031. procvardef^.concatdef(p,varspez);
  1032. s:=sc^.get;
  1033. end;
  1034. dispose(sc,done);
  1035. if token=SEMICOLON then consume(SEMICOLON)
  1036. else break;
  1037. until false;
  1038. dec(testcurobject);
  1039. consume(RKLAMMER);
  1040. end;
  1041. handle_procvar:=procvardef;
  1042. end;
  1043. var
  1044. hp1,p : pdef;
  1045. aufdef : penumdef;
  1046. aufsym : penumsym;
  1047. ap : parraydef;
  1048. s : stringid;
  1049. l,v,oldaktpackrecords : longint;
  1050. hs : string;
  1051. procedure expr_type;
  1052. var
  1053. pt1,pt2 : ptree;
  1054. begin
  1055. { use of current parsed object ? }
  1056. if (token=ID) and (testcurobject=2) and (curobjectname=pattern) then
  1057. begin
  1058. consume(ID);
  1059. p:=aktobjectdef;
  1060. exit;
  1061. end;
  1062. { we can't accept a equal in type }
  1063. pt1:=comp_expr(not(ignore_equal));
  1064. if (pt1^.treetype=typen) and (token<>POINTPOINT) then
  1065. begin
  1066. { a simple type renaming }
  1067. p:=pt1^.resulttype;
  1068. end
  1069. else
  1070. begin
  1071. { range type }
  1072. consume(POINTPOINT);
  1073. { range type declaration }
  1074. do_firstpass(pt1);
  1075. pt2:=comp_expr(not(ignore_equal));
  1076. do_firstpass(pt2);
  1077. { valid expression ? }
  1078. if (pt1^.treetype<>ordconstn) or
  1079. (pt2^.treetype<>ordconstn) then
  1080. Begin
  1081. Message(sym_e_error_in_type_def);
  1082. { Here we create a node type with a range of 0 }
  1083. { To make sure that no crashes will occur later }
  1084. { on in the compiler. }
  1085. p:=new(porddef,init(uauto,0,0));
  1086. end
  1087. else
  1088. p:=new(porddef,init(uauto,pt1^.value,pt2^.value));
  1089. disposetree(pt2);
  1090. end;
  1091. disposetree(pt1);
  1092. end;
  1093. var
  1094. pt : ptree;
  1095. procedure array_dec;
  1096. begin
  1097. consume(_ARRAY);
  1098. consume(LECKKLAMMER);
  1099. p:=nil;
  1100. repeat
  1101. { read the expression and check it }
  1102. pt:=expr;
  1103. if pt^.treetype=typen then
  1104. begin
  1105. if pt^.resulttype^.deftype=enumdef then
  1106. begin
  1107. if p=nil then
  1108. begin
  1109. ap:=new(parraydef,
  1110. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1111. p:=ap;
  1112. end
  1113. else
  1114. begin
  1115. ap^.definition:=new(parraydef,
  1116. init(0,penumdef(pt^.resulttype)^.max,pt^.resulttype));
  1117. ap:=parraydef(ap^.definition);
  1118. end;
  1119. end
  1120. else if pt^.resulttype^.deftype=orddef then
  1121. begin
  1122. case porddef(pt^.resulttype)^.typ of
  1123. s8bit,u8bit,s16bit,u16bit,s32bit :
  1124. begin
  1125. if p=nil then
  1126. begin
  1127. ap:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1128. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1129. p:=ap;
  1130. end
  1131. else
  1132. begin
  1133. ap^.definition:=new(parraydef,init(porddef(pt^.resulttype)^.von,
  1134. porddef(pt^.resulttype)^.bis,pt^.resulttype));
  1135. ap:=parraydef(ap^.definition);
  1136. end;
  1137. end;
  1138. bool8bit:
  1139. begin
  1140. if p=nil then
  1141. begin
  1142. ap:=new(parraydef,init(0,1,pt^.resulttype));
  1143. p:=ap;
  1144. end
  1145. else
  1146. begin
  1147. ap^.definition:=new(parraydef,init(0,1,pt^.resulttype));
  1148. ap:=parraydef(ap^.definition);
  1149. end;
  1150. end;
  1151. uchar:
  1152. begin
  1153. if p=nil then
  1154. begin
  1155. ap:=new(parraydef,init(0,255,pt^.resulttype));
  1156. p:=ap;
  1157. end
  1158. else
  1159. begin
  1160. ap^.definition:=new(parraydef,init(0,255,pt^.resulttype));
  1161. ap:=parraydef(ap^.definition);
  1162. end;
  1163. end;
  1164. else Message(sym_e_error_in_type_def);
  1165. end;
  1166. end
  1167. else Message(sym_e_error_in_type_def);
  1168. end
  1169. else
  1170. begin
  1171. do_firstpass(pt);
  1172. if (pt^.treetype<>rangen) or
  1173. (pt^.left^.treetype<>ordconstn) then
  1174. Message(sym_e_error_in_type_def);
  1175. { force the registration of the ranges }
  1176. {$ifndef GDB}
  1177. if pt^.right^.resulttype=pdef(s32bitdef) then
  1178. pt^.right^.resulttype:=new(porddef,init(
  1179. s32bit,$80000000,$7fffffff));
  1180. {$endif GDB}
  1181. if p=nil then
  1182. begin
  1183. ap:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1184. p:=ap;
  1185. end
  1186. else
  1187. begin
  1188. ap^.definition:=new(parraydef,init(pt^.left^.value,pt^.right^.value,pt^.right^.resulttype));
  1189. ap:=parraydef(ap^.definition);
  1190. end;
  1191. end;
  1192. disposetree(pt);
  1193. if token=COMMA then consume(COMMA)
  1194. else break;
  1195. until false;
  1196. consume(RECKKLAMMER);
  1197. consume(_OF);
  1198. hp1:=read_type('');
  1199. { if no error, set element type }
  1200. if assigned(ap) then
  1201. ap^.definition:=hp1;
  1202. end;
  1203. begin
  1204. case token of
  1205. _STRING,_FILE:
  1206. p:=single_type(hs);
  1207. LKLAMMER:
  1208. begin
  1209. consume(LKLAMMER);
  1210. l:=-1;
  1211. aufsym := Nil;
  1212. aufdef:=new(penumdef,init);
  1213. repeat
  1214. s:=pattern;
  1215. consume(ID);
  1216. if token=ASSIGNMENT then
  1217. begin
  1218. consume(ASSIGNMENT);
  1219. v:=get_intconst;
  1220. { please leave that a note, allows type save }
  1221. { declarations in the win32 units ! }
  1222. if v<=l then
  1223. Message(parser_n_duplicate_enum);
  1224. l:=v;
  1225. end
  1226. else
  1227. inc(l);
  1228. constsymtable^.insert(new(penumsym,init(s,aufdef,l)));
  1229. if token=COMMA then
  1230. consume(COMMA)
  1231. else
  1232. break;
  1233. until false;
  1234. aufdef^.max:=l;
  1235. p:=aufdef;
  1236. consume(RKLAMMER);
  1237. end;
  1238. _ARRAY:
  1239. array_dec;
  1240. _SET:
  1241. begin
  1242. consume(_SET);
  1243. consume(_OF);
  1244. hp1:=read_type('');
  1245. case hp1^.deftype of
  1246. enumdef : p:=new(psetdef,init(hp1,penumdef(hp1)^.max));
  1247. orddef : begin
  1248. case porddef(hp1)^.typ of
  1249. uchar : p:=new(psetdef,init(hp1,255));
  1250. u8bit,s8bit,u16bit,s16bit,s32bit :
  1251. begin
  1252. if (porddef(hp1)^.von>=0) then
  1253. p:=new(psetdef,init(hp1,porddef(hp1)^.bis))
  1254. else Message(sym_e_ill_type_decl_set);
  1255. end;
  1256. else Message(sym_e_ill_type_decl_set);
  1257. end;
  1258. end;
  1259. else Message(sym_e_ill_type_decl_set);
  1260. end;
  1261. end;
  1262. CARET:
  1263. begin
  1264. consume(CARET);
  1265. { forwards allowed only inside TYPE statements }
  1266. if typecanbeforward then
  1267. forwardsallowed:=true;
  1268. hp1:=single_type(hs);
  1269. p:=new(ppointerdef,init(hp1));
  1270. {$ifndef GDB}
  1271. if lasttypesym<>nil then
  1272. save_forward(ppointerdef(p),lasttypesym);
  1273. {$else * GDB *}
  1274. {I add big troubles here
  1275. with var p : ^byte in graph.putimage
  1276. because a save_forward was called and
  1277. no resolve forward
  1278. => so the definition was rewritten after
  1279. having been disposed !!
  1280. Strange problems appeared !!!!}
  1281. {Anyhow forwards should only be allowed
  1282. inside a type statement ??
  1283. don't you think so }
  1284. if (lasttypesym<>nil)
  1285. and ((lasttypesym^.properties and sp_forwarddef)<>0) then
  1286. lasttypesym^.forwardpointer:=ppointerdef(p);
  1287. {$endif * GDB *}
  1288. forwardsallowed:=false;
  1289. end;
  1290. _RECORD:
  1291. p:=record_dec;
  1292. _PACKED:
  1293. begin
  1294. consume(_PACKED);
  1295. if token=_ARRAY then
  1296. array_dec
  1297. else
  1298. begin
  1299. oldaktpackrecords:=aktpackrecords;
  1300. aktpackrecords:=1;
  1301. if token in [_CLASS,_OBJECT] then
  1302. p:=object_dec(name,nil)
  1303. else
  1304. p:=record_dec;
  1305. aktpackrecords:=oldaktpackrecords;
  1306. end;
  1307. end;
  1308. _CLASS,
  1309. _OBJECT:
  1310. p:=object_dec(name,nil);
  1311. _PROCEDURE:
  1312. begin
  1313. consume(_PROCEDURE);
  1314. p:=handle_procvar;
  1315. if token=_OF then
  1316. begin
  1317. consume(_OF);
  1318. consume(_OBJECT);
  1319. pprocvardef(p)^.options:=pprocvardef(p)^.options or pomethodpointer;
  1320. end;
  1321. end;
  1322. _FUNCTION:
  1323. begin
  1324. consume(_FUNCTION);
  1325. p:=handle_procvar;
  1326. consume(COLON);
  1327. pprocvardef(p)^.retdef:=single_type(hs);
  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. else
  1336. expr_type;
  1337. end;
  1338. read_type:=p;
  1339. end;
  1340. { search in symtablestack used, but not defined type }
  1341. procedure testforward_types(p : psym);{$ifndef FPC}far;{$endif}
  1342. begin
  1343. if (p^.typ=typesym) and ((p^.properties and sp_forwarddef)<>0) then
  1344. Message(sym_e_type_id_not_defined);
  1345. end;
  1346. { reads a type declaration to the symbol table }
  1347. procedure type_dec;
  1348. var
  1349. typename : stringid;
  1350. {$ifdef dummy}
  1351. olddef,newdef : pdef;
  1352. s : string;
  1353. {$endif dummy}
  1354. begin
  1355. block_type:=bt_type;
  1356. consume(_TYPE);
  1357. typecanbeforward:=true;
  1358. repeat
  1359. typename:=pattern;
  1360. consume(ID);
  1361. consume(EQUAL);
  1362. { here you loose the strictness of pascal
  1363. for which a redefinition like
  1364. childtype = parenttype;
  1365. child2type = parenttype;
  1366. does not make the two child types equal !!
  1367. here all vars from childtype and child2type
  1368. get the definition of parenttype !! }
  1369. {$ifdef testequaltype}
  1370. if (token = ID) or (token=_FILE) or (token=_STRING) then
  1371. begin
  1372. olddef := single_type(s);
  1373. { make a clone of olddef }
  1374. { is that ok ??? }
  1375. getmem(newdef,SizeOf(olddef));
  1376. move(olddef^,newdef^,SizeOf(olddef));
  1377. symtablestack^.insert(new(ptypesym,init(typename,newdef)));
  1378. end
  1379. else
  1380. {$endif testequaltype}
  1381. begin
  1382. getsym(typename,false);
  1383. { check if it is the definition of a forward defined class }
  1384. if assigned(srsym) and (token=_CLASS) and
  1385. (srsym^.typ=typesym) and
  1386. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  1387. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oo_isforward)<>0) and
  1388. ((pobjectdef(ptypesym(srsym)^.definition)^.options and oois_class)<>0) then
  1389. begin
  1390. { we can ignore the result }
  1391. { the definition is modified }
  1392. object_dec(typename,pobjectdef(ptypesym(srsym)^.definition));
  1393. end
  1394. else
  1395. symtablestack^.insert(new(ptypesym,init(typename,read_type(typename))));
  1396. end;
  1397. consume(SEMICOLON);
  1398. until token<>ID;
  1399. typecanbeforward:=false;
  1400. {$ifdef tp}
  1401. symtablestack^.foreach(testforward_types);
  1402. {$else}
  1403. symtablestack^.foreach(@testforward_types);
  1404. {$endif}
  1405. resolve_forwards;
  1406. block_type:=bt_general;
  1407. end;
  1408. { parses varaible declarations and inserts them in }
  1409. { the top symbol table of symtablestack }
  1410. procedure var_dec;
  1411. {var
  1412. p : pdef;
  1413. sc : pstringcontainer; }
  1414. begin
  1415. consume(_VAR);
  1416. read_var_decs(false,true);
  1417. end;
  1418. { reads the filed of a record into a }
  1419. { symtablestack, if record=false }
  1420. { variants are forbidden, so this procedure }
  1421. { can be used to read object fields }
  1422. { if absolute is true, ABSOLUTE and file }
  1423. { types are allowed }
  1424. { => the procedure is also used to read }
  1425. { a sequence of variable declaration }
  1426. procedure read_var_decs(is_record : boolean;do_absolute : boolean);
  1427. var
  1428. sc : pstringcontainer;
  1429. s : stringid;
  1430. l : longint;
  1431. code : word;
  1432. hs : string;
  1433. p,casedef : pdef;
  1434. { maxsize contains the max. size of a variant }
  1435. { startvarrec contains the start of the variant part of a record }
  1436. maxsize,startvarrec : longint;
  1437. pt : ptree;
  1438. old_block_type : tblock_type;
  1439. { to handle absolute }
  1440. abssym : pabsolutesym;
  1441. {$ifdef UseTokenInfo}
  1442. filepos : tfileposinfo;
  1443. {$endif UseTokenInfo}
  1444. begin
  1445. hs:='';
  1446. old_block_type:=block_type;
  1447. block_type:=bt_type;
  1448. while (token=ID) and
  1449. (pattern<>'PUBLIC') and
  1450. (pattern<>'PRIVATE') and
  1451. (pattern<>'PUBLISHED') and
  1452. (pattern<>'PROTECTED') do
  1453. begin
  1454. sc:=idlist;
  1455. consume(COLON);
  1456. p:=read_type('');
  1457. if do_absolute and (token=ID) and (pattern='ABSOLUTE') then
  1458. begin
  1459. {$ifdef UseTokenInfo}
  1460. s:=sc^.get_with_tokeninfo(filepos);
  1461. {$else UseTokenInfo}
  1462. s:=sc^.get;
  1463. {$endif UseTokenInfo}
  1464. if sc^.get<>'' then
  1465. Message(parser_e_absolute_only_one_var);
  1466. dispose(sc,done);
  1467. consume(ID);
  1468. if token=ID then
  1469. begin
  1470. getsym(pattern,true);
  1471. consume(ID);
  1472. { we should check the result type of srsym }
  1473. if not (srsym^.typ in [varsym,typedconstsym]) then
  1474. Message(parser_e_absolute_only_to_var_or_const);
  1475. abssym:=new(pabsolutesym,init(s,p));
  1476. abssym^.typ:=absolutesym;
  1477. abssym^.abstyp:=tovar;
  1478. abssym^.ref:=srsym;
  1479. {$ifdef UseTokenInfo}
  1480. abssym^.line_no:=filepos.line;
  1481. {$endif UseTokenInfo}
  1482. symtablestack^.insert(abssym);
  1483. end
  1484. else
  1485. if token=CSTRING then
  1486. begin
  1487. abssym:=new(pabsolutesym,init(s,p));
  1488. s:=pattern;
  1489. consume(CSTRING);
  1490. abssym^.typ:=absolutesym;
  1491. abssym^.abstyp:=toasm;
  1492. abssym^.asmname:=stringdup(s);
  1493. {$ifdef UseTokenInfo}
  1494. abssym^.line_no:=filepos.line;
  1495. {$endif UseTokenInfo}
  1496. symtablestack^.insert(abssym);
  1497. end
  1498. else
  1499. { absolute address ?!? }
  1500. if token=INTCONST then
  1501. begin
  1502. if (target_info.target=target_GO32V2) then
  1503. begin
  1504. abssym:=new(pabsolutesym,init(s,p));
  1505. abssym^.typ:=absolutesym;
  1506. abssym^.abstyp:=toaddr;
  1507. abssym^.absseg:=false;
  1508. {$ifdef UseTokenInfo}
  1509. abssym^.line_no:=filepos.line;
  1510. {$endif UseTokenInfo}
  1511. s:=pattern;
  1512. consume(INTCONST);
  1513. val(s,abssym^.address,code);
  1514. if token=COLON then
  1515. begin
  1516. consume(token);
  1517. s:=pattern;
  1518. consume(INTCONST);
  1519. val(s,l,code);
  1520. abssym^.address:=abssym^.address shl 4+l;
  1521. abssym^.absseg:=true;
  1522. end;
  1523. symtablestack^.insert(abssym);
  1524. end
  1525. else
  1526. Message(parser_e_absolute_only_to_var_or_const);
  1527. end
  1528. else
  1529. Message(parser_e_absolute_only_to_var_or_const);
  1530. end
  1531. else
  1532. begin
  1533. if token=SEMICOLON then
  1534. begin
  1535. if (symtablestack^.symtabletype=objectsymtable) then
  1536. begin
  1537. consume(SEMICOLON);
  1538. if (token=ID) and (pattern='STATIC') and
  1539. (cs_static_keyword in aktswitches) then
  1540. begin
  1541. current_object_option:=current_object_option or sp_static;
  1542. insert_syms(symtablestack,sc,p);
  1543. current_object_option:=current_object_option - sp_static;
  1544. consume(ID);
  1545. consume(SEMICOLON);
  1546. end
  1547. else
  1548. { this will still be a the wrong line !! }
  1549. insert_syms(symtablestack,sc,p);
  1550. end
  1551. else
  1552. begin
  1553. { at the right line }
  1554. insert_syms(symtablestack,sc,p);
  1555. consume(SEMICOLON);
  1556. end
  1557. end
  1558. else
  1559. begin
  1560. insert_syms(symtablestack,sc,p);
  1561. if not(is_record) then
  1562. consume(SEMICOLON);
  1563. end;
  1564. end;
  1565. while token=SEMICOLON do
  1566. consume(SEMICOLON);
  1567. end;
  1568. if (token=_CASE) and is_record then
  1569. begin
  1570. maxsize:=0;
  1571. consume(_CASE);
  1572. s:=pattern;
  1573. getsym(s,false);
  1574. { may be only a type: }
  1575. if assigned(srsym) and ((srsym^.typ=typesym) or
  1576. { and with unit qualifier: }
  1577. (srsym^.typ=unitsym)) then
  1578. begin
  1579. casedef:=read_type('');
  1580. end
  1581. else
  1582. begin
  1583. consume(ID);
  1584. consume(COLON);
  1585. casedef:=read_type('');
  1586. symtablestack^.insert(new(pvarsym,init(s,casedef)));
  1587. end;
  1588. if not is_ordinal(casedef) then
  1589. Message(parser_e_ordinal_expected);
  1590. consume(_OF);
  1591. startvarrec:=symtablestack^.datasize;
  1592. repeat
  1593. repeat
  1594. pt:=expr;
  1595. do_firstpass(pt);
  1596. if not(pt^.treetype=ordconstn) then
  1597. Message(cg_e_illegal_expression);
  1598. disposetree(pt);
  1599. if token=COMMA then consume(COMMA)
  1600. else break;
  1601. until false;
  1602. consume(COLON);
  1603. consume(LKLAMMER);
  1604. if token<>RKLAMMER then
  1605. read_var_decs(true,false);
  1606. { calculates maximal variant size }
  1607. maxsize:=max(maxsize,symtablestack^.datasize);
  1608. { the items of the next variant are overlayed }
  1609. symtablestack^.datasize:=startvarrec;
  1610. consume(RKLAMMER);
  1611. if token<>SEMICOLON then
  1612. break
  1613. else
  1614. consume(SEMICOLON);
  1615. while token=SEMICOLON do
  1616. consume(SEMICOLON);
  1617. until (token=_END) or (token=RKLAMMER);
  1618. { at last set the record size to that of the biggest variant }
  1619. symtablestack^.datasize:=maxsize;
  1620. end;
  1621. block_type:=old_block_type;
  1622. end;
  1623. procedure read_declarations(islibrary : boolean);
  1624. begin
  1625. repeat
  1626. case token of
  1627. _LABEL:
  1628. label_dec;
  1629. _CONST:
  1630. const_dec;
  1631. _TYPE:
  1632. type_dec;
  1633. _VAR:
  1634. var_dec;
  1635. _CONSTRUCTOR,_DESTRUCTOR,
  1636. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1637. unter_dec;
  1638. _EXPORTS:
  1639. if islibrary then
  1640. read_exports
  1641. else
  1642. break;
  1643. else break;
  1644. end;
  1645. until false;
  1646. end;
  1647. procedure read_interface_declarations;
  1648. begin
  1649. {Since the body is now parsed at lexlevel 1, and the declarations
  1650. must be parsed at the same lexlevel we increase the lexlevel.}
  1651. inc(lexlevel);
  1652. repeat
  1653. case token of
  1654. _CONST : const_dec;
  1655. _TYPE : type_dec;
  1656. _VAR : var_dec;
  1657. { should we allow operator in interface ? }
  1658. { of course otherwise you cannot }
  1659. { declare an operator usable by other }
  1660. { units or progs PM }
  1661. _FUNCTION,_PROCEDURE,_OPERATOR : unter_dec;
  1662. else
  1663. break;
  1664. end;
  1665. until false;
  1666. dec(lexlevel);
  1667. end;
  1668. end.
  1669. {
  1670. $Log$
  1671. Revision 1.13 1998-04-30 15:59:41 pierre
  1672. * GDB works again better :
  1673. correct type info in one pass
  1674. + UseTokenInfo for better source position
  1675. * fixed one remaining bug in scanner for line counts
  1676. * several little fixes
  1677. Revision 1.12 1998/04/29 10:33:57 pierre
  1678. + added some code for ansistring (not complete nor working yet)
  1679. * corrected operator overloading
  1680. * corrected nasm output
  1681. + started inline procedures
  1682. + added starstarn : use ** for exponentiation (^ gave problems)
  1683. + started UseTokenInfo cond to get accurate positions
  1684. Revision 1.11 1998/04/28 11:45:52 florian
  1685. * make it compilable with TP
  1686. + small COM problems solved to compile classes.pp
  1687. Revision 1.10 1998/04/27 23:10:28 peter
  1688. + new scanner
  1689. * $makelib -> if smartlink
  1690. * small filename fixes pmodule.setfilename
  1691. * moved import from files.pas -> import.pas
  1692. Revision 1.9 1998/04/10 21:36:56 florian
  1693. + some stuff to support method pointers (procedure of object) added
  1694. (declaration, parameter handling)
  1695. Revision 1.8 1998/04/10 15:39:48 florian
  1696. * more fixes to get classes.pas compiled
  1697. Revision 1.7 1998/04/09 23:02:15 florian
  1698. * small problems solved to get remake3 work
  1699. Revision 1.6 1998/04/09 22:16:35 florian
  1700. * problem with previous REGALLOC solved
  1701. * improved property support
  1702. Revision 1.5 1998/04/08 14:59:20 florian
  1703. * problem with new expr_type solved
  1704. Revision 1.4 1998/04/08 10:26:09 florian
  1705. * correct error handling of virtual constructors
  1706. * problem with new type declaration handling fixed
  1707. Revision 1.3 1998/04/07 22:45:05 florian
  1708. * bug0092, bug0115 and bug0121 fixed
  1709. + packed object/class/array
  1710. Revision 1.2 1998/04/05 13:58:35 peter
  1711. * fixed the -Ss bug
  1712. + warning for Virtual constructors
  1713. * helppages updated with -TGO32V1
  1714. Revision 1.1.1.1 1998/03/25 11:18:14 root
  1715. * Restored version
  1716. Revision 1.31 1998/03/24 21:48:33 florian
  1717. * just a couple of fixes applied:
  1718. - problem with fixed16 solved
  1719. - internalerror 10005 problem fixed
  1720. - patch for assembler reading
  1721. - small optimizer fix
  1722. - mem is now supported
  1723. Revision 1.30 1998/03/21 23:59:39 florian
  1724. * indexed properties fixed
  1725. * ppu i/o of properties fixed
  1726. * field can be also used for write access
  1727. * overriding of properties
  1728. Revision 1.29 1998/03/18 22:50:11 florian
  1729. + fstp/fld optimization
  1730. * routines which contains asm aren't longer optimzed
  1731. * wrong ifdef TEST_FUNCRET corrected
  1732. * wrong data generation for array[0..n] of char = '01234'; fixed
  1733. * bug0097 is fixed partial
  1734. * bug0116 fixed (-Og doesn't use enter of the stack frame is greater than
  1735. 65535)
  1736. Revision 1.28 1998/03/10 16:27:41 pierre
  1737. * better line info in stabs debug
  1738. * symtabletype and lexlevel separated into two fields of tsymtable
  1739. + ifdef MAKELIB for direct library output, not complete
  1740. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1741. working
  1742. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1743. working
  1744. Revision 1.27 1998/03/10 01:17:23 peter
  1745. * all files have the same header
  1746. * messages are fully implemented, EXTDEBUG uses Comment()
  1747. + AG... files for the Assembler generation
  1748. Revision 1.26 1998/03/06 00:52:41 peter
  1749. * replaced all old messages from errore.msg, only ExtDebug and some
  1750. Comment() calls are left
  1751. * fixed options.pas
  1752. Revision 1.25 1998/03/05 22:43:49 florian
  1753. * some win32 support stuff added
  1754. Revision 1.24 1998/03/04 17:33:49 michael
  1755. + Changed ifdef FPK to ifdef FPC
  1756. Revision 1.23 1998/03/04 01:35:06 peter
  1757. * messages for unit-handling and assembler/linker
  1758. * the compiler compiles without -dGDB, but doesn't work yet
  1759. + -vh for Hint
  1760. Revision 1.22 1998/03/02 01:49:00 peter
  1761. * renamed target_DOS to target_GO32V1
  1762. + new verbose system, merged old errors and verbose units into one new
  1763. verbose.pas, so errors.pas is obsolete
  1764. Revision 1.21 1998/02/28 14:43:47 florian
  1765. * final implemenation of win32 imports
  1766. * extended tai_align to allow 8 and 16 byte aligns
  1767. Revision 1.20 1998/02/19 00:11:07 peter
  1768. * fixed -g to work again
  1769. * fixed some typos with the scriptobject
  1770. Revision 1.19 1998/02/13 10:35:23 daniel
  1771. * Made Motorola version compilable.
  1772. * Fixed optimizer
  1773. Revision 1.18 1998/02/12 17:19:19 florian
  1774. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1775. also that aktswitches isn't a pointer)
  1776. Revision 1.17 1998/02/12 11:50:25 daniel
  1777. Yes! Finally! After three retries, my patch!
  1778. Changes:
  1779. Complete rewrite of psub.pas.
  1780. Added support for DLL's.
  1781. Compiler requires less memory.
  1782. Platform units for each platform.
  1783. Revision 1.16 1998/02/11 21:56:36 florian
  1784. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  1785. Revision 1.15 1998/02/06 10:34:25 florian
  1786. * bug0082 and bug0084 fixed
  1787. Revision 1.14 1998/02/02 11:56:49 pierre
  1788. * better line info for var statement
  1789. Revision 1.13 1998/01/30 21:25:31 carl
  1790. * bugfix #86 + checking of all other macros for crashes, fixed typeof
  1791. partly among others.
  1792. Revision 1.12 1998/01/23 17:12:19 pierre
  1793. * added some improvements for as and ld :
  1794. - doserror and dosexitcode treated separately
  1795. - PATH searched if doserror=2
  1796. + start of long and ansi string (far from complete)
  1797. in conditionnal UseLongString and UseAnsiString
  1798. * options.pas cleaned (some variables shifted to globals)gl
  1799. Revision 1.11 1998/01/21 21:25:46 florian
  1800. * small problem with variante records fixed:
  1801. case a : (x,y,z) of
  1802. ...
  1803. is now allowed
  1804. Revision 1.10 1998/01/13 23:11:13 florian
  1805. + class methods
  1806. Revision 1.9 1998/01/12 13:03:31 florian
  1807. + parsing of class methods implemented
  1808. Revision 1.8 1998/01/11 10:54:23 florian
  1809. + generic library support
  1810. Revision 1.7 1998/01/09 23:08:32 florian
  1811. + C++/Delphi styled //-comments
  1812. * some bugs in Delphi object model fixed
  1813. + override directive
  1814. Revision 1.6 1998/01/09 18:01:16 florian
  1815. * VIRTUAL isn't anymore a common keyword
  1816. + DYNAMIC is equal to VIRTUAL
  1817. Revision 1.5 1998/01/09 16:08:23 florian
  1818. * abstract methods call now abstracterrorproc if they are called
  1819. a class with an abstract method can be create with a class reference else
  1820. the compiler forbides this
  1821. Revision 1.4 1998/01/09 13:39:55 florian
  1822. * public, protected and private aren't anymore key words
  1823. + published is equal to public
  1824. Revision 1.3 1998/01/09 13:18:12 florian
  1825. + "forward" class declarations (type tclass = class; )
  1826. Revision 1.2 1998/01/09 09:09:58 michael
  1827. + Initial implementation, second try
  1828. }