pdecl.pas 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. {
  2. $Id$
  3. Copyright (c) 1993-99 by Florian Klaempfl
  4. Does declaration (but not type) 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. globtype,tokens,globals,symtable;
  22. procedure parameter_dec(aktprocdef:pabstractprocdef);
  23. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  24. { reads the declaration blocks }
  25. procedure read_declarations(islibrary : boolean);
  26. { reads declarations in the interface part of a unit }
  27. procedure read_interface_declarations;
  28. implementation
  29. uses
  30. cobjects,scanner,
  31. symconst,aasm,tree,pass_1,strings,
  32. files,types,verbose,systems,import,
  33. cpubase
  34. {$ifndef newcg}
  35. ,tccnv
  36. {$endif newcg}
  37. {$ifdef GDB}
  38. ,gdb
  39. {$endif GDB}
  40. { parser specific stuff }
  41. ,pbase,ptconst,pexpr,ptype,psub,pexports
  42. { processor specific stuff }
  43. { codegen }
  44. {$ifdef newcg}
  45. ,cgbase
  46. {$else}
  47. ,hcodegen
  48. {$endif}
  49. ,hcgdata
  50. ;
  51. procedure parameter_dec(aktprocdef:pabstractprocdef);
  52. {
  53. handle_procvar needs the same changes
  54. }
  55. var
  56. is_procvar : boolean;
  57. sc : Pstringcontainer;
  58. s : string;
  59. storetokenpos : tfileposinfo;
  60. tt : ttype;
  61. hsym : psym;
  62. hvs,
  63. vs : Pvarsym;
  64. hs1,hs2 : string;
  65. varspez : Tvarspez;
  66. inserthigh : boolean;
  67. begin
  68. { parsing a proc or procvar ? }
  69. is_procvar:=(aktprocdef^.deftype=procvardef);
  70. consume(_LKLAMMER);
  71. inc(testcurobject);
  72. repeat
  73. if try_to_consume(_VAR) then
  74. varspez:=vs_var
  75. else
  76. if try_to_consume(_CONST) then
  77. varspez:=vs_const
  78. else
  79. varspez:=vs_value;
  80. inserthigh:=false;
  81. tt.reset;
  82. if idtoken=_SELF then
  83. begin
  84. { only allowed in procvars and class methods }
  85. if is_procvar or
  86. (assigned(procinfo^._class) and procinfo^._class^.is_class) then
  87. begin
  88. if not is_procvar then
  89. begin
  90. {$ifndef UseNiceNames}
  91. hs2:=hs2+'$'+'self';
  92. {$else UseNiceNames}
  93. hs2:=hs2+tostr(length('self'))+'self';
  94. {$endif UseNiceNames}
  95. vs:=new(Pvarsym,initdef('@',procinfo^._class));
  96. vs^.varspez:=vs_var;
  97. { insert the sym in the parasymtable }
  98. pprocdef(aktprocdef)^.parast^.insert(vs);
  99. {$ifdef INCLUDEOK}
  100. include(aktprocdef^.procoptions,po_containsself);
  101. {$else}
  102. aktprocdef^.procoptions:=aktprocdef^.procoptions+[po_containsself];
  103. {$endif}
  104. inc(procinfo^.selfpointer_offset,vs^.address);
  105. end;
  106. consume(idtoken);
  107. consume(_COLON);
  108. single_type(tt,hs1,false);
  109. aktprocdef^.concatpara(tt,vs_value);
  110. { check the types for procedures only }
  111. if not is_procvar then
  112. CheckTypes(tt.def,procinfo^._class);
  113. end
  114. else
  115. consume(_ID);
  116. end
  117. else
  118. begin
  119. { read identifiers }
  120. sc:=idlist;
  121. { read type declaration, force reading for value and const paras }
  122. if (token=_COLON) or (varspez=vs_value) then
  123. begin
  124. consume(_COLON);
  125. { check for an open array }
  126. if token=_ARRAY then
  127. begin
  128. consume(_ARRAY);
  129. consume(_OF);
  130. { define range and type of range }
  131. tt.setdef(new(Parraydef,init(0,-1,s32bitdef)));
  132. { array of const ? }
  133. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  134. begin
  135. consume(_CONST);
  136. srsym:=nil;
  137. getsymonlyin(systemunit,'TVARREC');
  138. if not assigned(srsym) then
  139. InternalError(1234124);
  140. Parraydef(tt.def)^.elementtype:=ptypesym(srsym)^.restype;
  141. Parraydef(tt.def)^.IsArrayOfConst:=true;
  142. hs1:='array_of_const';
  143. end
  144. else
  145. begin
  146. { define field type }
  147. single_type(parraydef(tt.def)^.elementtype,hs1,false);
  148. hs1:='array_of_'+hs1;
  149. end;
  150. inserthigh:=true;
  151. end
  152. { open string ? }
  153. else if (varspez=vs_var) and
  154. (
  155. (
  156. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  157. (cs_openstring in aktmoduleswitches) and
  158. not(cs_ansistrings in aktlocalswitches)
  159. ) or
  160. (idtoken=_OPENSTRING)) then
  161. begin
  162. consume(token);
  163. tt.setdef(openshortstringdef);
  164. hs1:='openstring';
  165. inserthigh:=true;
  166. end
  167. { everything else }
  168. else
  169. single_type(tt,hs1,false);
  170. end
  171. else
  172. begin
  173. {$ifndef UseNiceNames}
  174. hs1:='$$$';
  175. {$else UseNiceNames}
  176. hs1:='var';
  177. {$endif UseNiceNames}
  178. tt.setdef(cformaldef);
  179. end;
  180. if not is_procvar then
  181. hs2:=pprocdef(aktprocdef)^.mangledname;
  182. storetokenpos:=tokenpos;
  183. while not sc^.empty do
  184. begin
  185. s:=sc^.get_with_tokeninfo(tokenpos);
  186. aktprocdef^.concatpara(tt,varspez);
  187. { For proc vars we only need the definitions }
  188. if not is_procvar then
  189. begin
  190. {$ifndef UseNiceNames}
  191. hs2:=hs2+'$'+hs1;
  192. {$else UseNiceNames}
  193. hs2:=hs2+tostr(length(hs1))+hs1;
  194. {$endif UseNiceNames}
  195. vs:=new(pvarsym,init(s,tt));
  196. vs^.varspez:=varspez;
  197. { we have to add this to avoid var param to be in registers !!!}
  198. if (varspez in [vs_var,vs_const]) and push_addr_param(tt.def) then
  199. {$ifdef INCLUDEOK}
  200. include(vs^.varoptions,vo_regable);
  201. {$else}
  202. vs^.varoptions:=vs^.varoptions+[vo_regable];
  203. {$endif}
  204. { search for duplicate ids in object members/methods }
  205. { but only the current class, I don't know why ... }
  206. { at least TP and Delphi do it in that way (FK) }
  207. if assigned(procinfo^._class) and
  208. (lexlevel=normal_function_level) then
  209. begin
  210. hsym:=procinfo^._class^.symtable^.search(vs^.name);
  211. if assigned(hsym) then
  212. DuplicateSym(hsym);
  213. end;
  214. { do we need a local copy? }
  215. if (varspez=vs_value) and
  216. push_addr_param(tt.def) and
  217. not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
  218. vs^.setname('val'+vs^.name);
  219. { insert the sym in the parasymtable }
  220. pprocdef(aktprocdef)^.parast^.insert(vs);
  221. { also need to push a high value? }
  222. if inserthigh then
  223. begin
  224. hvs:=new(Pvarsym,initdef('high'+s,s32bitdef));
  225. hvs^.varspez:=vs_const;
  226. pprocdef(aktprocdef)^.parast^.insert(hvs);
  227. end;
  228. end;
  229. end;
  230. dispose(sc,done);
  231. tokenpos:=storetokenpos;
  232. end;
  233. { set the new mangled name }
  234. if not is_procvar then
  235. pprocdef(aktprocdef)^.setmangledname(hs2);
  236. until not try_to_consume(_SEMICOLON);
  237. dec(testcurobject);
  238. consume(_RKLAMMER);
  239. end;
  240. const
  241. variantrecordlevel : longint = 0;
  242. procedure read_var_decs(is_record,is_object,is_threadvar:boolean);
  243. { reads the filed of a record into a }
  244. { symtablestack, if record=false }
  245. { variants are forbidden, so this procedure }
  246. { can be used to read object fields }
  247. { if absolute is true, ABSOLUTE and file }
  248. { types are allowed }
  249. { => the procedure is also used to read }
  250. { a sequence of variable declaration }
  251. procedure insert_syms(st : psymtable;sc : pstringcontainer;tt : ttype;is_threadvar : boolean);
  252. { inserts the symbols of sc in st with def as definition or sym as ptypesym, sc is disposed }
  253. var
  254. s : string;
  255. filepos : tfileposinfo;
  256. ss : pvarsym;
  257. begin
  258. filepos:=tokenpos;
  259. while not sc^.empty do
  260. begin
  261. s:=sc^.get_with_tokeninfo(tokenpos);
  262. ss:=new(pvarsym,init(s,tt));
  263. if is_threadvar then
  264. {$ifdef INCLUDEOK}
  265. include(ss^.varoptions,vo_is_thread_var);
  266. {$else}
  267. ss^.varoptions:=ss^.varoptions+[vo_is_thread_var];
  268. {$endif}
  269. st^.insert(ss);
  270. { static data fields are inserted in the globalsymtable }
  271. if (st^.symtabletype=objectsymtable) and
  272. (sp_static in current_object_option) then
  273. begin
  274. s:=lower(st^.name^)+'_'+s;
  275. st^.defowner^.owner^.insert(new(pvarsym,init(s,tt)));
  276. end;
  277. end;
  278. dispose(sc,done);
  279. tokenpos:=filepos;
  280. end;
  281. var
  282. sc : pstringcontainer;
  283. s : stringid;
  284. old_block_type : tblock_type;
  285. declarepos,storetokenpos : tfileposinfo;
  286. symdone : boolean;
  287. { to handle absolute }
  288. abssym : pabsolutesym;
  289. l : longint;
  290. code : integer;
  291. { c var }
  292. newtype : ptypesym;
  293. is_dll,
  294. is_gpc_name,is_cdecl,extern_aktvarsym,export_aktvarsym : boolean;
  295. old_current_object_option : tsymoptions;
  296. dll_name,
  297. C_name : string;
  298. tt,casetype : ttype;
  299. { Delphi initialized vars }
  300. pconstsym : ptypedconstsym;
  301. { maxsize contains the max. size of a variant }
  302. { startvarrec contains the start of the variant part of a record }
  303. maxsize,startvarrec : longint;
  304. pt : ptree;
  305. begin
  306. old_block_type:=block_type;
  307. block_type:=bt_type;
  308. is_gpc_name:=false;
  309. { Force an expected ID error message }
  310. if not (token in [_ID,_CASE,_END]) then
  311. consume(_ID);
  312. { read vars }
  313. while (token=_ID) and
  314. not(is_object and (idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED])) do
  315. begin
  316. C_name:=orgpattern;
  317. sc:=idlist;
  318. consume(_COLON);
  319. if (m_gpc in aktmodeswitches) and
  320. not(is_record or is_object or is_threadvar) and
  321. (token=_ID) and (orgpattern='__asmname__') then
  322. begin
  323. consume(_ID);
  324. C_name:=pattern;
  325. if token=_CCHAR then
  326. consume(_CCHAR)
  327. else
  328. consume(_CSTRING);
  329. Is_gpc_name:=true;
  330. end;
  331. { this is needed for Delphi mode at least
  332. but should be OK for all modes !! (PM) }
  333. ignore_equal:=true;
  334. read_type(tt,'');
  335. if (variantrecordlevel>0) and tt.def^.needs_inittable then
  336. Message(parser_e_cant_use_inittable_here);
  337. ignore_equal:=false;
  338. symdone:=false;
  339. if is_gpc_name then
  340. begin
  341. storetokenpos:=tokenpos;
  342. s:=sc^.get_with_tokeninfo(tokenpos);
  343. if not sc^.empty then
  344. Message(parser_e_absolute_only_one_var);
  345. dispose(sc,done);
  346. aktvarsym:=new(pvarsym,init_C(s,target_os.Cprefix+C_name,tt));
  347. {$ifdef INCLUDEOK}
  348. include(aktvarsym^.varoptions,vo_is_external);
  349. {$else}
  350. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  351. {$endif}
  352. symtablestack^.insert(aktvarsym);
  353. tokenpos:=storetokenpos;
  354. symdone:=true;
  355. end;
  356. { check for absolute }
  357. if not symdone and
  358. (idtoken=_ABSOLUTE) and not(is_record or is_object or is_threadvar) then
  359. begin
  360. consume(_ABSOLUTE);
  361. { only allowed for one var }
  362. s:=sc^.get_with_tokeninfo(declarepos);
  363. if not sc^.empty then
  364. Message(parser_e_absolute_only_one_var);
  365. dispose(sc,done);
  366. { parse the rest }
  367. if token=_ID then
  368. begin
  369. getsym(pattern,true);
  370. consume(_ID);
  371. { support unit.variable }
  372. if srsym^.typ=unitsym then
  373. begin
  374. consume(_POINT);
  375. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  376. consume(_ID);
  377. end;
  378. { we should check the result type of srsym }
  379. if not (srsym^.typ in [varsym,typedconstsym]) then
  380. Message(parser_e_absolute_only_to_var_or_const);
  381. storetokenpos:=tokenpos;
  382. tokenpos:=declarepos;
  383. abssym:=new(pabsolutesym,init(s,tt));
  384. abssym^.abstyp:=tovar;
  385. abssym^.ref:=srsym;
  386. symtablestack^.insert(abssym);
  387. tokenpos:=storetokenpos;
  388. end
  389. else
  390. if (token=_CSTRING) or (token=_CCHAR) then
  391. begin
  392. storetokenpos:=tokenpos;
  393. tokenpos:=declarepos;
  394. abssym:=new(pabsolutesym,init(s,tt));
  395. s:=pattern;
  396. consume(token);
  397. abssym^.abstyp:=toasm;
  398. abssym^.asmname:=stringdup(s);
  399. symtablestack^.insert(abssym);
  400. tokenpos:=storetokenpos;
  401. end
  402. else
  403. { absolute address ?!? }
  404. if token=_INTCONST then
  405. begin
  406. if (target_info.target=target_i386_go32v2) then
  407. begin
  408. storetokenpos:=tokenpos;
  409. tokenpos:=declarepos;
  410. abssym:=new(pabsolutesym,init(s,tt));
  411. abssym^.abstyp:=toaddr;
  412. abssym^.absseg:=false;
  413. s:=pattern;
  414. consume(_INTCONST);
  415. val(s,abssym^.address,code);
  416. if token=_COLON then
  417. begin
  418. consume(token);
  419. s:=pattern;
  420. consume(_INTCONST);
  421. val(s,l,code);
  422. abssym^.address:=abssym^.address shl 4+l;
  423. abssym^.absseg:=true;
  424. end;
  425. symtablestack^.insert(abssym);
  426. tokenpos:=storetokenpos;
  427. end
  428. else
  429. Message(parser_e_absolute_only_to_var_or_const);
  430. end
  431. else
  432. Message(parser_e_absolute_only_to_var_or_const);
  433. symdone:=true;
  434. end;
  435. { Handling of Delphi typed const = initialized vars ! }
  436. { When should this be rejected ?
  437. - in parasymtable
  438. - in record or object
  439. - ... (PM) }
  440. if (m_delphi in aktmodeswitches) and (token=_EQUAL) and
  441. not (symtablestack^.symtabletype in [parasymtable]) and
  442. not is_record and not is_object then
  443. begin
  444. storetokenpos:=tokenpos;
  445. s:=sc^.get_with_tokeninfo(tokenpos);
  446. if not sc^.empty then
  447. Message(parser_e_initialized_only_one_var);
  448. pconstsym:=new(ptypedconstsym,inittype(s,tt,false));
  449. symtablestack^.insert(pconstsym);
  450. tokenpos:=storetokenpos;
  451. consume(_EQUAL);
  452. readtypedconst(tt.def,pconstsym,false);
  453. symdone:=true;
  454. end;
  455. { for a record there doesn't need to be a ; before the END or ) }
  456. if not((is_record or is_object) and (token in [_END,_RKLAMMER])) then
  457. consume(_SEMICOLON);
  458. { procvar handling }
  459. if (tt.def^.deftype=procvardef) and (tt.def^.typesym=nil) then
  460. begin
  461. newtype:=new(ptypesym,init('unnamed',tt));
  462. parse_var_proc_directives(psym(newtype));
  463. newtype^.restype.def:=nil;
  464. tt.def^.typesym:=nil;
  465. dispose(newtype,done);
  466. end;
  467. { Check for variable directives }
  468. if not symdone and (token=_ID) then
  469. begin
  470. { Check for C Variable declarations }
  471. if (m_cvar_support in aktmodeswitches) and
  472. not(is_record or is_object or is_threadvar) and
  473. (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) then
  474. begin
  475. { only allowed for one var }
  476. s:=sc^.get_with_tokeninfo(declarepos);
  477. if not sc^.empty then
  478. Message(parser_e_absolute_only_one_var);
  479. dispose(sc,done);
  480. { defaults }
  481. is_dll:=false;
  482. is_cdecl:=false;
  483. extern_aktvarsym:=false;
  484. export_aktvarsym:=false;
  485. { cdecl }
  486. if idtoken=_CVAR then
  487. begin
  488. consume(_CVAR);
  489. consume(_SEMICOLON);
  490. is_cdecl:=true;
  491. C_name:=target_os.Cprefix+C_name;
  492. end;
  493. { external }
  494. if idtoken=_EXTERNAL then
  495. begin
  496. consume(_EXTERNAL);
  497. extern_aktvarsym:=true;
  498. end;
  499. { export }
  500. if idtoken in [_EXPORT,_PUBLIC] then
  501. begin
  502. consume(_ID);
  503. if extern_aktvarsym then
  504. Message(parser_e_not_external_and_export)
  505. else
  506. export_aktvarsym:=true;
  507. end;
  508. { external and export need a name after when no cdecl is used }
  509. if not is_cdecl then
  510. begin
  511. { dll name ? }
  512. if (extern_aktvarsym) and (idtoken<>_NAME) then
  513. begin
  514. is_dll:=true;
  515. dll_name:=get_stringconst;
  516. end;
  517. consume(_NAME);
  518. C_name:=get_stringconst;
  519. end;
  520. { consume the ; when export or external is used }
  521. if extern_aktvarsym or export_aktvarsym then
  522. consume(_SEMICOLON);
  523. { insert in the symtable }
  524. storetokenpos:=tokenpos;
  525. tokenpos:=declarepos;
  526. if is_dll then
  527. aktvarsym:=new(pvarsym,init_dll(s,tt))
  528. else
  529. aktvarsym:=new(pvarsym,init_C(s,C_name,tt));
  530. { set some vars options }
  531. if export_aktvarsym then
  532. inc(aktvarsym^.refs);
  533. if extern_aktvarsym then
  534. {$ifdef INCLUDEOK}
  535. include(aktvarsym^.varoptions,vo_is_external);
  536. {$else}
  537. aktvarsym^.varoptions:=aktvarsym^.varoptions+[vo_is_external];
  538. {$endif}
  539. { insert in the stack/datasegment }
  540. symtablestack^.insert(aktvarsym);
  541. tokenpos:=storetokenpos;
  542. { now we can insert it in the import lib if its a dll, or
  543. add it to the externals }
  544. if extern_aktvarsym then
  545. begin
  546. if is_dll then
  547. begin
  548. if not(current_module^.uses_imports) then
  549. begin
  550. current_module^.uses_imports:=true;
  551. importlib^.preparelib(current_module^.modulename^);
  552. end;
  553. importlib^.importvariable(aktvarsym^.mangledname,dll_name,C_name)
  554. end
  555. end;
  556. symdone:=true;
  557. end
  558. else
  559. if (is_object) and (cs_static_keyword in aktmoduleswitches) and (idtoken=_STATIC) then
  560. begin
  561. {$ifdef INCLUDEOK}
  562. include(current_object_option,sp_static);
  563. {$else}
  564. current_object_option:=current_object_option+[sp_static];
  565. {$endif}
  566. insert_syms(symtablestack,sc,tt,false);
  567. {$ifdef INCLUDEOK}
  568. exclude(current_object_option,sp_static);
  569. {$else}
  570. current_object_option:=current_object_option-[sp_static];
  571. {$endif}
  572. consume(_STATIC);
  573. consume(_SEMICOLON);
  574. symdone:=true;
  575. end;
  576. end;
  577. { insert it in the symtable, if not done yet }
  578. if not symdone then
  579. begin
  580. { save object option, because we can turn of the sp_published }
  581. old_current_object_option:=current_object_option;
  582. if (sp_published in current_object_option) and
  583. (not((tt.def^.deftype=objectdef) and (pobjectdef(tt.def)^.is_class))) then
  584. begin
  585. Message(parser_e_cant_publish_that);
  586. exclude(current_object_option,sp_published);
  587. end
  588. else
  589. if (sp_published in current_object_option) and
  590. not(oo_can_have_published in pobjectdef(tt.def)^.objectoptions) then
  591. begin
  592. Message(parser_e_only_publishable_classes_can__be_published);
  593. exclude(current_object_option,sp_published);
  594. end;
  595. insert_syms(symtablestack,sc,tt,is_threadvar);
  596. current_object_option:=old_current_object_option;
  597. end;
  598. end;
  599. { Check for Case }
  600. if is_record and (token=_CASE) then
  601. begin
  602. maxsize:=0;
  603. consume(_CASE);
  604. s:=pattern;
  605. getsym(s,false);
  606. { may be only a type: }
  607. if assigned(srsym) and (srsym^.typ in [typesym,unitsym]) then
  608. read_type(casetype,'')
  609. else
  610. begin
  611. consume(_ID);
  612. consume(_COLON);
  613. read_type(casetype,'');
  614. symtablestack^.insert(new(pvarsym,init(s,casetype)));
  615. end;
  616. if not(is_ordinal(casetype.def)) or is_64bitint(casetype.def) then
  617. Message(type_e_ordinal_expr_expected);
  618. consume(_OF);
  619. startvarrec:=symtablestack^.datasize;
  620. repeat
  621. repeat
  622. pt:=comp_expr(true);
  623. do_firstpass(pt);
  624. if not(pt^.treetype=ordconstn) then
  625. Message(cg_e_illegal_expression);
  626. disposetree(pt);
  627. if token=_COMMA then
  628. consume(_COMMA)
  629. else
  630. break;
  631. until false;
  632. consume(_COLON);
  633. { read the vars }
  634. consume(_LKLAMMER);
  635. inc(variantrecordlevel);
  636. if token<>_RKLAMMER then
  637. read_var_decs(true,false,false);
  638. dec(variantrecordlevel);
  639. consume(_RKLAMMER);
  640. { calculates maximal variant size }
  641. maxsize:=max(maxsize,symtablestack^.datasize);
  642. { the items of the next variant are overlayed }
  643. symtablestack^.datasize:=startvarrec;
  644. if (token<>_END) and (token<>_RKLAMMER) then
  645. consume(_SEMICOLON)
  646. else
  647. break;
  648. until (token=_END) or (token=_RKLAMMER);
  649. { at last set the record size to that of the biggest variant }
  650. symtablestack^.datasize:=maxsize;
  651. end;
  652. block_type:=old_block_type;
  653. end;
  654. procedure const_dec;
  655. var
  656. name : stringid;
  657. p : ptree;
  658. tt : ttype;
  659. sym : psym;
  660. storetokenpos,filepos : tfileposinfo;
  661. old_block_type : tblock_type;
  662. ps : pconstset;
  663. pd : pbestreal;
  664. sp : pchar;
  665. skipequal : boolean;
  666. begin
  667. consume(_CONST);
  668. old_block_type:=block_type;
  669. block_type:=bt_const;
  670. repeat
  671. name:=pattern;
  672. filepos:=tokenpos;
  673. consume(_ID);
  674. case token of
  675. _EQUAL:
  676. begin
  677. consume(_EQUAL);
  678. p:=comp_expr(true);
  679. do_firstpass(p);
  680. storetokenpos:=tokenpos;
  681. tokenpos:=filepos;
  682. case p^.treetype of
  683. ordconstn:
  684. begin
  685. if is_constintnode(p) then
  686. symtablestack^.insert(new(pconstsym,init_def(name,constint,p^.value,nil)))
  687. else if is_constcharnode(p) then
  688. symtablestack^.insert(new(pconstsym,init_def(name,constchar,p^.value,nil)))
  689. else if is_constboolnode(p) then
  690. symtablestack^.insert(new(pconstsym,init_def(name,constbool,p^.value,nil)))
  691. else if p^.resulttype^.deftype=enumdef then
  692. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  693. else if p^.resulttype^.deftype=pointerdef then
  694. symtablestack^.insert(new(pconstsym,init_def(name,constord,p^.value,p^.resulttype)))
  695. else internalerror(111);
  696. end;
  697. stringconstn:
  698. begin
  699. getmem(sp,p^.length+1);
  700. move(p^.value_str^,sp^,p^.length+1);
  701. symtablestack^.insert(new(pconstsym,init_string(name,conststring,sp,p^.length)));
  702. end;
  703. realconstn :
  704. begin
  705. new(pd);
  706. pd^:=p^.value_real;
  707. symtablestack^.insert(new(pconstsym,init(name,constreal,longint(pd))));
  708. end;
  709. setconstn :
  710. begin
  711. new(ps);
  712. ps^:=p^.value_set^;
  713. symtablestack^.insert(new(pconstsym,init_def(name,constset,longint(ps),p^.resulttype)));
  714. end;
  715. pointerconstn :
  716. begin
  717. symtablestack^.insert(new(pconstsym,init_def(name,constpointer,p^.value,p^.resulttype)))
  718. end;
  719. niln :
  720. begin
  721. symtablestack^.insert(new(pconstsym,init_def(name,constnil,0,p^.resulttype)));
  722. end;
  723. else
  724. Message(cg_e_illegal_expression);
  725. end;
  726. tokenpos:=storetokenpos;
  727. consume(_SEMICOLON);
  728. disposetree(p);
  729. end;
  730. _COLON:
  731. begin
  732. { set the blocktype first so a consume also supports a
  733. caret, to support const s : ^string = nil }
  734. block_type:=bt_type;
  735. consume(_COLON);
  736. ignore_equal:=true;
  737. read_type(tt,'');
  738. ignore_equal:=false;
  739. block_type:=bt_const;
  740. skipequal:=false;
  741. { create symbol }
  742. storetokenpos:=tokenpos;
  743. tokenpos:=filepos;
  744. {$ifdef DELPHI_CONST_IN_RODATA}
  745. if m_delphi in aktmodeswitches then
  746. begin
  747. if assigned(readtypesym) then
  748. sym:=new(ptypedconstsym,initsym(name,readtypesym,true))
  749. else
  750. sym:=new(ptypedconstsym,init(name,def,true))
  751. end
  752. else
  753. {$endif DELPHI_CONST_IN_RODATA}
  754. begin
  755. sym:=new(ptypedconstsym,inittype(name,tt,false))
  756. end;
  757. tokenpos:=storetokenpos;
  758. symtablestack^.insert(sym);
  759. { procvar can have proc directives }
  760. if (tt.def^.deftype=procvardef) then
  761. begin
  762. { support p : procedure;stdcall=nil; }
  763. if (token=_SEMICOLON) then
  764. begin
  765. consume(_SEMICOLON);
  766. if is_proc_directive(token) then
  767. parse_var_proc_directives(sym)
  768. else
  769. begin
  770. Message(parser_e_proc_directive_expected);
  771. skipequal:=true;
  772. end;
  773. end
  774. else
  775. { support p : procedure stdcall=nil; }
  776. begin
  777. if is_proc_directive(token) then
  778. parse_var_proc_directives(sym);
  779. end;
  780. end;
  781. if not skipequal then
  782. begin
  783. { get init value }
  784. consume(_EQUAL);
  785. {$ifdef DELPHI_CONST_IN_RODATA}
  786. if m_delphi in aktmodeswitches then
  787. readtypedconst(tt.def,ptypedconstsym(sym),true)
  788. else
  789. {$endif DELPHI_CONST_IN_RODATA}
  790. readtypedconst(tt.def,ptypedconstsym(sym),false);
  791. consume(_SEMICOLON);
  792. end;
  793. end;
  794. else
  795. { generate an error }
  796. consume(_EQUAL);
  797. end;
  798. until token<>_ID;
  799. block_type:=old_block_type;
  800. end;
  801. procedure label_dec;
  802. var
  803. hl : pasmlabel;
  804. begin
  805. consume(_LABEL);
  806. if not(cs_support_goto in aktmoduleswitches) then
  807. Message(sym_e_goto_and_label_not_supported);
  808. repeat
  809. if not(token in [_ID,_INTCONST]) then
  810. consume(_ID)
  811. else
  812. begin
  813. getlabel(hl);
  814. symtablestack^.insert(new(plabelsym,init(pattern,hl)));
  815. consume(token);
  816. end;
  817. if token<>_SEMICOLON then consume(_COMMA);
  818. until not(token in [_ID,_INTCONST]);
  819. consume(_SEMICOLON);
  820. end;
  821. { search in symtablestack used, but not defined type }
  822. procedure resolve_type_forward(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
  823. var
  824. hpd,pd : pdef;
  825. stpos : tfileposinfo;
  826. begin
  827. { Check only typesyms or record/object fields }
  828. case psym(p)^.typ of
  829. typesym :
  830. pd:=ptypesym(p)^.restype.def;
  831. varsym :
  832. if (psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  833. pd:=pvarsym(p)^.vartype.def
  834. else
  835. exit;
  836. else
  837. exit;
  838. end;
  839. case pd^.deftype of
  840. pointerdef,
  841. classrefdef :
  842. begin
  843. { classrefdef inherits from pointerdef }
  844. hpd:=ppointerdef(pd)^.pointertype.def;
  845. { still a forward def ? }
  846. if hpd^.deftype=forwarddef then
  847. begin
  848. { try to resolve the forward }
  849. { get the correct position for it }
  850. stpos:=tokenpos;
  851. tokenpos:=pforwarddef(hpd)^.forwardpos;
  852. resolving_forward:=true;
  853. getsym(pforwarddef(hpd)^.tosymname,false);
  854. resolving_forward:=false;
  855. tokenpos:=stpos;
  856. { we don't need the forwarddef anymore, dispose it }
  857. dispose(hpd,done);
  858. { was a type sym found ? }
  859. if assigned(srsym) and
  860. (srsym^.typ=typesym) then
  861. begin
  862. ppointerdef(pd)^.pointertype.def:=ptypesym(srsym)^.restype.def;
  863. {$ifdef GDB}
  864. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  865. (psym(p)^.owner^.symtabletype in [globalsymtable,staticsymtable]) then
  866. begin
  867. ptypesym(p)^.isusedinstab := true;
  868. psym(p)^.concatstabto(debuglist);
  869. end;
  870. {$endif GDB}
  871. { we need a class type for classrefdef }
  872. if (pd^.deftype=classrefdef) and
  873. not((ptypesym(srsym)^.restype.def^.deftype=objectdef) and
  874. pobjectdef(ptypesym(srsym)^.restype.def)^.is_class) then
  875. Message1(type_e_class_type_expected,ptypesym(srsym)^.restype.def^.typename);
  876. end
  877. else
  878. begin
  879. MessagePos1(psym(p)^.fileinfo,sym_e_forward_type_not_resolved,p^.name);
  880. { try to recover }
  881. ppointerdef(pd)^.pointertype.def:=generrordef;
  882. end;
  883. end;
  884. end;
  885. recorddef :
  886. precorddef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  887. objectdef :
  888. { Don't check objectdefs in objects/records, because these can't
  889. exist (anonymous objects aren't allowed) }
  890. if not(psym(p)^.owner^.symtabletype in [objectsymtable,recordsymtable]) then
  891. pobjectdef(pd)^.symtable^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  892. end;
  893. end;
  894. { reads a type declaration to the symbol table }
  895. procedure type_dec;
  896. var
  897. typename : stringid;
  898. newtype : ptypesym;
  899. sym : psym;
  900. tt : ttype;
  901. defpos,storetokenpos : tfileposinfo;
  902. old_block_type : tblock_type;
  903. begin
  904. old_block_type:=block_type;
  905. block_type:=bt_type;
  906. consume(_TYPE);
  907. typecanbeforward:=true;
  908. repeat
  909. typename:=pattern;
  910. defpos:=tokenpos;
  911. consume(_ID);
  912. consume(_EQUAL);
  913. { support 'ttype=type word' syntax }
  914. if token=_TYPE then
  915. Consume(_TYPE);
  916. { is the type already defined? }
  917. getsym(typename,false);
  918. sym:=srsym;
  919. newtype:=nil;
  920. { found a symbol with this name? }
  921. if assigned(sym) then
  922. begin
  923. if (sym^.typ=typesym) then
  924. begin
  925. if (token=_CLASS) and
  926. (assigned(ptypesym(sym)^.restype.def)) and
  927. (ptypesym(sym)^.restype.def^.deftype=objectdef) and
  928. pobjectdef(ptypesym(sym)^.restype.def)^.is_class and
  929. (oo_is_forward in pobjectdef(ptypesym(sym)^.restype.def)^.objectoptions) then
  930. begin
  931. { we can ignore the result }
  932. { the definition is modified }
  933. object_dec(typename,pobjectdef(ptypesym(sym)^.restype.def));
  934. newtype:=ptypesym(sym);
  935. end;
  936. end;
  937. end;
  938. { no old type reused ? Then insert this new type }
  939. if not assigned(newtype) then
  940. begin
  941. read_type(tt,typename);
  942. storetokenpos:=tokenpos;
  943. tokenpos:=defpos;
  944. newtype:=new(ptypesym,init(typename,tt));
  945. newtype:=ptypesym(symtablestack^.insert(newtype));
  946. tokenpos:=storetokenpos;
  947. end;
  948. consume(_SEMICOLON);
  949. if assigned(newtype^.restype.def) and
  950. (newtype^.restype.def^.deftype=procvardef) then
  951. parse_var_proc_directives(psym(newtype));
  952. until token<>_ID;
  953. typecanbeforward:=false;
  954. symtablestack^.foreach({$ifndef TP}@{$endif}resolve_type_forward);
  955. block_type:=old_block_type;
  956. end;
  957. procedure var_dec;
  958. { parses variable declarations and inserts them in }
  959. { the top symbol table of symtablestack }
  960. begin
  961. consume(_VAR);
  962. read_var_decs(false,false,false);
  963. end;
  964. procedure threadvar_dec;
  965. { parses thread variable declarations and inserts them in }
  966. { the top symbol table of symtablestack }
  967. begin
  968. consume(_THREADVAR);
  969. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  970. message(parser_e_threadvars_only_sg);
  971. read_var_decs(false,false,true);
  972. end;
  973. procedure resourcestring_dec;
  974. var
  975. name : stringid;
  976. p : ptree;
  977. storetokenpos,filepos : tfileposinfo;
  978. old_block_type : tblock_type;
  979. sp : pchar;
  980. begin
  981. consume(_RESOURCESTRING);
  982. if not(symtablestack^.symtabletype in [staticsymtable,globalsymtable]) then
  983. message(parser_e_resourcestring_only_sg);
  984. old_block_type:=block_type;
  985. block_type:=bt_const;
  986. repeat
  987. name:=pattern;
  988. filepos:=tokenpos;
  989. consume(_ID);
  990. case token of
  991. _EQUAL:
  992. begin
  993. consume(_EQUAL);
  994. p:=comp_expr(true);
  995. do_firstpass(p);
  996. storetokenpos:=tokenpos;
  997. tokenpos:=filepos;
  998. case p^.treetype of
  999. ordconstn:
  1000. begin
  1001. if is_constcharnode(p) then
  1002. begin
  1003. getmem(sp,2);
  1004. sp[0]:=chr(p^.value);
  1005. sp[1]:=#0;
  1006. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,1)));
  1007. end
  1008. else
  1009. Message(cg_e_illegal_expression);
  1010. end;
  1011. stringconstn:
  1012. begin
  1013. getmem(sp,p^.length+1);
  1014. move(p^.value_str^,sp^,p^.length+1);
  1015. symtablestack^.insert(new(pconstsym,init_string(name,constresourcestring,sp,p^.length)));
  1016. end;
  1017. else
  1018. Message(cg_e_illegal_expression);
  1019. end;
  1020. tokenpos:=storetokenpos;
  1021. consume(_SEMICOLON);
  1022. disposetree(p);
  1023. end;
  1024. else consume(_EQUAL);
  1025. end;
  1026. until token<>_ID;
  1027. block_type:=old_block_type;
  1028. end;
  1029. procedure Not_supported_for_inline(t : ttoken);
  1030. begin
  1031. if assigned(aktprocsym) and
  1032. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  1033. Begin
  1034. Message1(parser_w_not_supported_for_inline,tokenstring(t));
  1035. Message(parser_w_inlining_disabled);
  1036. {$ifdef INCLUDEOK}
  1037. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  1038. {$else}
  1039. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions-[pocall_inline];
  1040. {$endif}
  1041. End;
  1042. end;
  1043. procedure read_declarations(islibrary : boolean);
  1044. begin
  1045. repeat
  1046. case token of
  1047. _LABEL:
  1048. begin
  1049. Not_supported_for_inline(token);
  1050. label_dec;
  1051. end;
  1052. _CONST:
  1053. begin
  1054. Not_supported_for_inline(token);
  1055. const_dec;
  1056. end;
  1057. _TYPE:
  1058. begin
  1059. Not_supported_for_inline(token);
  1060. type_dec;
  1061. end;
  1062. _VAR:
  1063. var_dec;
  1064. _THREADVAR:
  1065. threadvar_dec;
  1066. _CONSTRUCTOR,_DESTRUCTOR,
  1067. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  1068. begin
  1069. Not_supported_for_inline(token);
  1070. read_proc;
  1071. end;
  1072. _RESOURCESTRING:
  1073. resourcestring_dec;
  1074. _EXPORTS:
  1075. begin
  1076. Not_supported_for_inline(token);
  1077. { here we should be at lexlevel 1, no ? PM }
  1078. if (lexlevel<>main_program_level) or
  1079. (current_module^.is_unit) then
  1080. begin
  1081. Message(parser_e_syntax_error);
  1082. consume_all_until(_SEMICOLON);
  1083. end
  1084. else if islibrary or (target_info.target=target_i386_WIN32) then
  1085. read_exports;
  1086. end
  1087. else break;
  1088. end;
  1089. until false;
  1090. end;
  1091. procedure read_interface_declarations;
  1092. begin
  1093. {Since the body is now parsed at lexlevel 1, and the declarations
  1094. must be parsed at the same lexlevel we increase the lexlevel.}
  1095. inc(lexlevel);
  1096. repeat
  1097. case token of
  1098. _CONST : const_dec;
  1099. _TYPE : type_dec;
  1100. _VAR : var_dec;
  1101. _THREADVAR : threadvar_dec;
  1102. _RESOURCESTRING:
  1103. resourcestring_dec;
  1104. _FUNCTION,
  1105. _PROCEDURE,
  1106. _OPERATOR : read_proc;
  1107. else
  1108. break;
  1109. end;
  1110. until false;
  1111. dec(lexlevel);
  1112. end;
  1113. end.
  1114. {
  1115. $Log$
  1116. Revision 1.174 1999-12-01 12:42:32 peter
  1117. * fixed bug 698
  1118. * removed some notes about unused vars
  1119. Revision 1.173 1999/11/30 10:40:44 peter
  1120. + ttype, tsymlist
  1121. Revision 1.172 1999/11/29 15:18:27 pierre
  1122. + allow exports in win32 executables
  1123. Revision 1.171 1999/11/09 23:43:08 pierre
  1124. * better browser info
  1125. Revision 1.170 1999/11/09 23:06:45 peter
  1126. * esi_offset -> selfpointer_offset to be newcg compatible
  1127. * hcogegen -> cgbase fixes for newcg
  1128. Revision 1.169 1999/11/09 12:58:29 peter
  1129. * support absolute unit.variable
  1130. Revision 1.168 1999/11/06 14:34:21 peter
  1131. * truncated log to 20 revs
  1132. Revision 1.167 1999/10/26 12:30:44 peter
  1133. * const parameter is now checked
  1134. * better and generic check if a node can be used for assigning
  1135. * export fixes
  1136. * procvar equal works now (it never had worked at least from 0.99.8)
  1137. * defcoll changed to linkedlist with pparaitem so it can easily be
  1138. walked both directions
  1139. Revision 1.166 1999/10/22 10:39:34 peter
  1140. * split type reading from pdecl to ptype unit
  1141. * parameter_dec routine is now used for procedure and procvars
  1142. Revision 1.165 1999/10/21 16:41:41 florian
  1143. * problems with readln fixed: esi wasn't restored correctly when
  1144. reading ordinal fields of objects futher the register allocation
  1145. didn't take care of the extra register when reading ordinal values
  1146. * enumerations can now be used in constant indexes of properties
  1147. Revision 1.164 1999/10/14 14:57:52 florian
  1148. - removed the hcodegen use in the new cg, use cgbase instead
  1149. Revision 1.163 1999/10/06 17:39:14 peter
  1150. * fixed stabs writting for forward types
  1151. Revision 1.162 1999/10/03 19:44:42 peter
  1152. * removed objpasunit reference, tvarrec is now searched in systemunit
  1153. where it already was located
  1154. Revision 1.161 1999/10/01 11:18:02 peter
  1155. * class/record type forward checking fixed
  1156. Revision 1.159 1999/10/01 10:05:42 peter
  1157. + procedure directive support in const declarations, fixes bug 232
  1158. Revision 1.158 1999/10/01 08:02:46 peter
  1159. * forward type declaration rewritten
  1160. Revision 1.157 1999/09/27 23:44:53 peter
  1161. * procinfo is now a pointer
  1162. * support for result setting in sub procedure
  1163. Revision 1.156 1999/09/26 21:30:19 peter
  1164. + constant pointer support which can happend with typecasting like
  1165. const p=pointer(1)
  1166. * better procvar parsing in typed consts
  1167. Revision 1.155 1999/09/20 16:38:59 peter
  1168. * cs_create_smart instead of cs_smartlink
  1169. * -CX is create smartlink
  1170. * -CD is create dynamic, but does nothing atm.
  1171. Revision 1.154 1999/09/15 22:09:24 florian
  1172. + rtti is now automatically generated for published classes, i.e.
  1173. they are handled like an implicit property
  1174. Revision 1.153 1999/09/14 11:09:08 florian
  1175. * per default a property is stored, fixed
  1176. Revision 1.152 1999/09/12 14:50:50 florian
  1177. + implemented creation of methodname/address tables
  1178. Revision 1.151 1999/09/12 08:48:09 florian
  1179. * bugs 593 and 607 fixed
  1180. * some other potential bugs with array constructors fixed
  1181. * for classes compiled in $M+ and it's childs, the default access method
  1182. is now published
  1183. * fixed copyright message (it is now 1993-99)
  1184. Revision 1.150 1999/09/10 20:57:33 florian
  1185. * some more fixes for stored properties
  1186. Revision 1.149 1999/09/10 18:48:07 florian
  1187. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  1188. * most things for stored properties fixed
  1189. Revision 1.148 1999/09/08 21:06:06 michael
  1190. * Stored specifier for properties is now correctly parsed
  1191. Revision 1.147 1999/09/02 09:23:51 peter
  1192. * fixed double dispose of propsymlist
  1193. }