pdecl.pas 47 KB

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