pdecvar.pas 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Parses variable declarations. Used for var statement and record
  4. definitions
  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 pdecvar;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. symtable,symsym,symdef,symtype;
  24. type
  25. tvar_dec_option=(vd_record,vd_object,vd_threadvar,vd_class,vd_final,vd_canreorder,vd_check_generic);
  26. tvar_dec_options=set of tvar_dec_option;
  27. function read_property_dec(is_classproperty:boolean;astruct:tabstractrecorddef):tpropertysym;
  28. procedure read_var_decls(options:Tvar_dec_options;out had_generic:boolean);
  29. procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc: ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
  30. procedure read_public_and_external(vs: tabstractvarsym);
  31. procedure try_consume_sectiondirective(var asection: ansistring);
  32. function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
  33. implementation
  34. uses
  35. SysUtils,
  36. { common }
  37. cutils,
  38. { global }
  39. globtype,globals,tokens,verbose,constexp,
  40. systems,
  41. { symtable }
  42. symconst,symbase,defutil,defcmp,symutil,symcreat,
  43. {$if defined(i386) or defined(i8086) or defined(wasm)}
  44. symcpu,
  45. {$endif}
  46. fmodule,htypechk,procdefutil,
  47. { pass 1 }
  48. node,pass_1,aasmbase,aasmdata,
  49. ncon,nset,ncnv,nld,nutils,
  50. { codegen }
  51. ngenutil,
  52. { parser }
  53. scanner,
  54. pbase,pexpr,ptype,ptconst,pdecsub,pparautl;
  55. function read_property_dec(is_classproperty:boolean;astruct:tabstractrecorddef):tpropertysym;
  56. { convert a node tree to symlist and return the last
  57. symbol }
  58. function parse_symlist(pl:tpropaccesslist;out def:tdef):boolean;
  59. var
  60. idx : longint;
  61. sym : tsym;
  62. srsymtable : TSymtable;
  63. st : TSymtable;
  64. p : tnode;
  65. begin
  66. result:=true;
  67. def:=nil;
  68. if token=_ID then
  69. begin
  70. if assigned(astruct) then
  71. sym:=search_struct_member(astruct,pattern)
  72. else
  73. searchsym(pattern,sym,srsymtable);
  74. if assigned(sym) then
  75. begin
  76. if assigned(astruct) and
  77. not is_visible_for_object(sym,astruct) then
  78. Message(parser_e_cant_access_private_member);
  79. case sym.typ of
  80. fieldvarsym :
  81. begin
  82. addsymref(sym);
  83. pl.addsym(sl_load,sym);
  84. def:=tfieldvarsym(sym).vardef;
  85. end;
  86. procsym :
  87. begin
  88. addsymref(sym);
  89. pl.addsym(sl_call,sym);
  90. end;
  91. else
  92. begin
  93. Message1(parser_e_illegal_field_or_method,orgpattern);
  94. def:=generrordef;
  95. result:=false;
  96. end;
  97. end;
  98. end
  99. else
  100. begin
  101. Message1(parser_e_illegal_field_or_method,orgpattern);
  102. def:=generrordef;
  103. result:=false;
  104. end;
  105. consume(_ID);
  106. repeat
  107. case token of
  108. _ID,
  109. _SEMICOLON :
  110. begin
  111. break;
  112. end;
  113. _POINT :
  114. begin
  115. if not is_object(def) and not is_record(def) then
  116. message(sym_e_type_must_be_rec_or_object);
  117. consume(_POINT);
  118. if assigned(def) then
  119. begin
  120. st:=def.GetSymtable(gs_record);
  121. if assigned(st) then
  122. begin
  123. sym:=tsym(st.Find(pattern));
  124. if not(assigned(sym)) and is_object(def) then
  125. sym:=search_struct_member(tobjectdef(def),pattern);
  126. if assigned(sym) then
  127. begin
  128. pl.addsym(sl_subscript,sym);
  129. case sym.typ of
  130. fieldvarsym :
  131. def:=tfieldvarsym(sym).vardef;
  132. else
  133. begin
  134. Message1(sym_e_illegal_field,orgpattern);
  135. result:=false;
  136. end;
  137. end;
  138. end
  139. else
  140. begin
  141. Message1(sym_e_illegal_field,orgpattern);
  142. result:=false;
  143. end;
  144. end
  145. else
  146. begin
  147. Message(parser_e_invalid_qualifier);
  148. result:=false;
  149. end;
  150. end
  151. else
  152. begin
  153. Message(parser_e_invalid_qualifier);
  154. result:=false;
  155. end;
  156. consume(_ID);
  157. end;
  158. _LECKKLAMMER :
  159. begin
  160. consume(_LECKKLAMMER);
  161. repeat
  162. if assigned(def) and (def.typ=arraydef) then
  163. begin
  164. idx:=0;
  165. p:=comp_expr([ef_accept_equal]);
  166. if (not codegenerror) then
  167. begin
  168. if (p.nodetype=ordconstn) then
  169. begin
  170. { type/range checking }
  171. inserttypeconv(p,tarraydef(def).rangedef);
  172. if (Tordconstnode(p).value<int64(low(longint))) or
  173. (Tordconstnode(p).value>int64(high(longint))) then
  174. message(parser_e_array_range_out_of_bounds)
  175. else
  176. idx:=Tordconstnode(p).value.svalue
  177. end
  178. else
  179. Message(type_e_ordinal_expr_expected)
  180. end;
  181. pl.addconst(sl_vec,idx,p.resultdef);
  182. p.free;
  183. p := nil;
  184. def:=tarraydef(def).elementdef;
  185. end
  186. else
  187. begin
  188. Message(parser_e_invalid_qualifier);
  189. result:=false;
  190. end;
  191. until not try_to_consume(_COMMA);
  192. consume(_RECKKLAMMER);
  193. end;
  194. else
  195. begin
  196. Message(parser_e_ill_property_access_sym);
  197. result:=false;
  198. break;
  199. end;
  200. end;
  201. until false;
  202. end
  203. else
  204. begin
  205. Message(parser_e_ill_property_access_sym);
  206. result:=false;
  207. end;
  208. end;
  209. function has_implicit_default(p : tpropertysym) : boolean;
  210. begin
  211. has_implicit_default:=
  212. (is_string(p.propdef) or
  213. is_real(p.propdef) or
  214. is_pointer(p.propdef));
  215. end;
  216. function allow_default_property(p : tpropertysym) : boolean;
  217. begin
  218. allow_default_property:=
  219. (is_ordinal(p.propdef) or
  220. {$ifndef cpu64bitaddr}
  221. is_64bitint(p.propdef) or
  222. {$endif cpu64bitaddr}
  223. is_class(p.propdef) or
  224. is_single(p.propdef) or
  225. (p.propdef.typ in [classrefdef,pointerdef]) or
  226. is_smallset(p.propdef)
  227. ) and not
  228. (
  229. (p.propdef.typ=arraydef) and
  230. (ppo_indexed in p.propoptions)
  231. ) and not
  232. (ppo_hasparameters in p.propoptions);
  233. end;
  234. procedure create_accessor_procsym(p: tpropertysym; pd: tprocdef; const prefix: string;
  235. accesstype: tpropaccesslisttypes);
  236. var
  237. sym: tprocsym;
  238. begin
  239. if not assigned(astruct) then
  240. handle_calling_convention(pd,hcc_default_actions_intf)
  241. else
  242. handle_calling_convention(pd,hcc_default_actions_intf_struct);
  243. sym:=cprocsym.create(prefix+lower(p.realname));
  244. symtablestack.top.insertsym(sym);
  245. pd.procsym:=sym;
  246. include(pd.procoptions,po_dispid);
  247. include(pd.procoptions,po_global);
  248. pd.visibility:=vis_private;
  249. proc_add_definition(pd);
  250. p.propaccesslist[accesstype].addsym(sl_call,sym);
  251. p.propaccesslist[accesstype].procdef:=pd;
  252. end;
  253. procedure parse_dispinterface(p : tpropertysym; readpd,writepd: tprocdef;
  254. var paranr: word);
  255. var
  256. hasread, haswrite: boolean;
  257. pt: tnode;
  258. hdispid: longint;
  259. hparavs: tparavarsym;
  260. begin
  261. p.propaccesslist[palt_read].clear;
  262. p.propaccesslist[palt_write].clear;
  263. hasread:=true;
  264. haswrite:=true;
  265. hdispid:=0;
  266. if try_to_consume(_READONLY) then
  267. haswrite:=false
  268. else if try_to_consume(_WRITEONLY) then
  269. hasread:=false;
  270. if try_to_consume(_DISPID) then
  271. begin
  272. pt:=comp_expr([ef_accept_equal]);
  273. if is_constintnode(pt) then
  274. if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
  275. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(longint)),tostr(high(longint)))
  276. else
  277. hdispid:=Tordconstnode(pt).value.svalue
  278. else
  279. Message(parser_e_dispid_must_be_ord_const);
  280. pt.free;
  281. pt := nil;
  282. end
  283. else
  284. hdispid:=tobjectdef(astruct).get_next_dispid;
  285. { COM property is simply a pair of methods, tagged with 'propertyget'
  286. and 'propertyset' flags (or a single method if access is restricted).
  287. Creating these implicit accessor methods also allows the rest of compiler
  288. to handle dispinterface properties the same way as regular ones. }
  289. if hasread then
  290. begin
  291. readpd.returndef:=p.propdef;
  292. readpd.dispid:=hdispid;
  293. readpd.proctypeoption:=potype_propgetter;
  294. create_accessor_procsym(p,readpd,'get$',palt_read);
  295. end;
  296. if haswrite then
  297. begin
  298. { add an extra parameter, a placeholder of the value to set }
  299. inc(paranr);
  300. hparavs:=cparavarsym.create('$value',10*paranr,vs_value,p.propdef,[]);
  301. writepd.parast.insertsym(hparavs);
  302. writepd.proctypeoption:=potype_propsetter;
  303. writepd.dispid:=hdispid;
  304. create_accessor_procsym(p,writepd,'put$',palt_write);
  305. end;
  306. end;
  307. var
  308. sym : tsym;
  309. srsymtable: tsymtable;
  310. p : tpropertysym;
  311. overridden : tsym;
  312. varspez : tvarspez;
  313. hdef : tdef;
  314. arraytype : tdef;
  315. def : tdef;
  316. pt : tnode;
  317. sc : TFPObjectList;
  318. paranr : word;
  319. i : longint;
  320. ImplIntf : TImplementedInterface;
  321. found,
  322. gotreadorwrite: boolean;
  323. hreadparavs,
  324. hparavs : tparavarsym;
  325. storedprocdef: tprocvardef;
  326. readprocdef,
  327. writeprocdef : tprocdef;
  328. begin
  329. result:=nil;
  330. { Generate temp procdefs to search for matching read/write
  331. procedures. the readprocdef will store all definitions }
  332. paranr:=0;
  333. readprocdef:=cprocdef.create(normal_function_level,false);
  334. writeprocdef:=cprocdef.create(normal_function_level,false);
  335. readprocdef.struct:=astruct;
  336. writeprocdef.struct:=astruct;
  337. if assigned(astruct) and is_classproperty then
  338. begin
  339. readprocdef.procoptions:=[po_staticmethod,po_classmethod];
  340. writeprocdef.procoptions:=[po_staticmethod,po_classmethod];
  341. end;
  342. if token<>_ID then
  343. begin
  344. consume(_ID);
  345. consume(_SEMICOLON);
  346. exit;
  347. end;
  348. { Generate propertysym and insert in symtablestack }
  349. p:=cpropertysym.create(orgpattern);
  350. p.visibility:=symtablestack.top.currentvisibility;
  351. p.default:=longint($80000000);
  352. if is_classproperty then
  353. include(p.symoptions, sp_static);
  354. symtablestack.top.insertsym(p);
  355. consume(_ID);
  356. { property parameters ? }
  357. if try_to_consume(_LECKKLAMMER) then
  358. begin
  359. { Published indexed properties are allowed in Delphi in interfaces compiled with $M+. }
  360. if (p.visibility=vis_published) and
  361. not((m_delphi in current_settings.modeswitches) and is_interfacecom_or_dispinterface(astruct)) then
  362. Message(parser_e_cant_publish_that_property);
  363. { create a list of the parameters }
  364. p.parast:=tparasymtable.create(nil,0);
  365. symtablestack.push(p.parast);
  366. sc:=TFPObjectList.create(false);
  367. repeat
  368. if try_to_consume(_VAR) then
  369. varspez:=vs_var
  370. else if try_to_consume(_CONST) then
  371. varspez:=vs_const
  372. else if try_to_consume(_CONSTREF) then
  373. varspez:=vs_constref
  374. else if (m_out in current_settings.modeswitches) and try_to_consume(_OUT) then
  375. varspez:=vs_out
  376. else
  377. varspez:=vs_value;
  378. sc.clear;
  379. repeat
  380. inc(paranr);
  381. hreadparavs:=cparavarsym.create(orgpattern,10*paranr,varspez,generrordef,[]);
  382. p.parast.insertsym(hreadparavs);
  383. sc.add(hreadparavs);
  384. consume(_ID);
  385. until not try_to_consume(_COMMA);
  386. if try_to_consume(_COLON) then
  387. begin
  388. if try_to_consume(_ARRAY) then
  389. begin
  390. consume(_OF);
  391. { define range and type of range }
  392. hdef:=carraydef.create_openarray;
  393. hdef.owner:=astruct.symtable;
  394. { define field type }
  395. single_type(arraytype,[]);
  396. tarraydef(hdef).elementdef:=arraytype;
  397. end
  398. else
  399. single_type(hdef,[]);
  400. end
  401. else
  402. hdef:=cformaltype;
  403. for i:=0 to sc.count-1 do
  404. tparavarsym(sc[i]).vardef:=hdef;
  405. until not try_to_consume(_SEMICOLON);
  406. sc.free;
  407. sc := nil;
  408. symtablestack.pop(p.parast);
  409. consume(_RECKKLAMMER);
  410. { the parser need to know if a property has parameters, the
  411. index parameter doesn't count (PFV) }
  412. if paranr>0 then
  413. begin
  414. p.add_accessor_parameters(readprocdef,writeprocdef);
  415. include(p.propoptions,ppo_hasparameters);
  416. end;
  417. end;
  418. { overridden property ? }
  419. { force property interface
  420. there is a property parameter
  421. a global property }
  422. if (token=_COLON) or (paranr>0) or (astruct=nil) then
  423. begin
  424. consume(_COLON);
  425. single_type(p.propdef,[stoAllowSpecialization]);
  426. if is_dispinterface(astruct) and not is_automatable(p.propdef) then
  427. Message1(type_e_not_automatable,p.propdef.typename);
  428. if (idtoken=_INDEX) then
  429. begin
  430. consume(_INDEX);
  431. pt:=comp_expr([ef_accept_equal]);
  432. { Only allow enum and integer indexes. Convert all integer
  433. values to objpas.integer (s32int on 32- and 64-bit targets,
  434. s16int on 16- and 8-bit) to be compatible with delphi,
  435. because the procedure matching requires equal parameters }
  436. if is_constnode(pt) and
  437. is_ordinal(pt.resultdef)
  438. and (not is_64bitint(pt.resultdef))
  439. {$if defined(cpu8bitalu) or defined(cpu16bitalu)}
  440. and (not is_32bitint(pt.resultdef))
  441. {$endif}
  442. then
  443. begin
  444. if is_integer(pt.resultdef) then
  445. {$if defined(cpu8bitalu) or defined(cpu16bitalu)}
  446. inserttypeconv_internal(pt,s16inttype);
  447. {$else}
  448. inserttypeconv_internal(pt,s32inttype);
  449. {$endif}
  450. p.index:=tordconstnode(pt).value.svalue;
  451. end
  452. else
  453. begin
  454. Message(parser_e_invalid_property_index_value);
  455. p.index:=0;
  456. end;
  457. p.indexdef:=pt.resultdef;
  458. include(p.propoptions,ppo_indexed);
  459. { concat a longint to the para templates }
  460. p.add_index_parameter(paranr,readprocdef,writeprocdef);
  461. pt.free;
  462. pt := nil;
  463. end;
  464. end
  465. else
  466. begin
  467. { do an property override }
  468. if (astruct.typ=objectdef) and assigned(tobjectdef(astruct).childof) then
  469. overridden:=search_struct_member(tobjectdef(astruct).childof,p.name)
  470. else
  471. overridden:=nil;
  472. if assigned(overridden) and
  473. (overridden.typ=propertysym) and
  474. not(is_dispinterface(astruct)) then
  475. begin
  476. tpropertysym(overridden).makeduplicate(p,readprocdef,writeprocdef,paranr);
  477. p.register_override(tpropertysym(overridden));
  478. end
  479. else
  480. begin
  481. p.propdef:=generrordef;
  482. message(parser_e_no_property_found_to_override);
  483. end;
  484. end;
  485. if ((p.visibility=vis_published) or is_dispinterface(astruct))
  486. and not (astruct.is_generic and (p.propdef.typ=undefineddef)) then
  487. begin
  488. { ignore is_publishable for interfaces (related to $M+ directive).
  489. $M has effect on visibility of default section for classes.
  490. Interface has always only public section (fix for problem in tb0631.pp) }
  491. if (sp_static in p.symoptions) or ((p.propdef.is_publishable=pp_error) and not is_interface(astruct)) then
  492. begin
  493. Message(parser_e_cant_publish_that_property);
  494. p.visibility:=vis_public;
  495. end
  496. else
  497. if (p.propdef.is_publishable=pp_ignore) and not is_interface(astruct) then
  498. begin
  499. Message(parser_w_ignoring_published_property);
  500. p.visibility:=vis_public;
  501. end;
  502. end;
  503. if not(is_dispinterface(astruct)) then
  504. begin
  505. gotreadorwrite:=false;
  506. { parse accessors }
  507. if try_to_consume(_READ) then
  508. begin
  509. gotreadorwrite:=true;
  510. p.propaccesslist[palt_read].clear;
  511. if parse_symlist(p.propaccesslist[palt_read],def) then
  512. begin
  513. sym:=p.propaccesslist[palt_read].firstsym^.sym;
  514. { getter is a function returning the type of the property }
  515. if sym.typ=procsym then
  516. begin
  517. readprocdef.returndef:=p.propdef;
  518. { Insert hidden parameters }
  519. if assigned(astruct) then
  520. handle_calling_convention(readprocdef,hcc_default_actions_intf_struct)
  521. else
  522. handle_calling_convention(readprocdef,hcc_default_actions_intf);
  523. end;
  524. p.add_getter_or_setter_for_sym(palt_read,sym,def,readprocdef);
  525. end;
  526. end
  527. else
  528. p.inherit_accessor(palt_read);
  529. if try_to_consume(_WRITE) then
  530. begin
  531. gotreadorwrite:=true;
  532. p.propaccesslist[palt_write].clear;
  533. if parse_symlist(p.propaccesslist[palt_write],def) then
  534. begin
  535. sym:=p.propaccesslist[palt_write].firstsym^.sym;
  536. if sym.typ=procsym then
  537. begin
  538. { setter is a procedure with an extra value parameter
  539. of the of the property }
  540. writeprocdef.returndef:=voidtype;
  541. inc(paranr);
  542. hparavs:=cparavarsym.create('$value',10*paranr,vs_value,p.propdef,[]);
  543. writeprocdef.parast.insertsym(hparavs);
  544. { Insert hidden parameters }
  545. if not assigned(astruct) then
  546. handle_calling_convention(writeprocdef,hcc_default_actions_intf)
  547. else
  548. handle_calling_convention(writeprocdef,hcc_default_actions_intf_struct);
  549. end;
  550. p.add_getter_or_setter_for_sym(palt_write,sym,def,writeprocdef);
  551. end;
  552. end
  553. else
  554. p.inherit_accessor(palt_write);
  555. { a new property (needs to declare a getter or setter, except in
  556. an interface }
  557. if not(ppo_overrides in p.propoptions) and
  558. not is_interface(astruct) and
  559. not gotreadorwrite then
  560. Consume(_READ);
  561. end
  562. else
  563. parse_dispinterface(p,readprocdef,writeprocdef,paranr);
  564. { stored is not allowed for dispinterfaces, records or class properties }
  565. if assigned(astruct) and not(is_dispinterface(astruct) or is_record(astruct)) and not is_classproperty then
  566. begin
  567. { ppo_stored is default on for not overridden properties }
  568. if not assigned(p.overriddenpropsym) then
  569. include(p.propoptions,ppo_stored);
  570. if try_to_consume(_STORED) then
  571. begin
  572. include(p.propoptions,ppo_stored);
  573. p.propaccesslist[palt_stored].clear;
  574. if token=_ID then
  575. begin
  576. { in the case that idtoken=_DEFAULT }
  577. { we have to do nothing except }
  578. { setting ppo_stored, it's the same }
  579. { as stored true }
  580. if idtoken<>_DEFAULT then
  581. begin
  582. { parse_symlist cannot deal with constsyms, and
  583. we also don't want to put constsyms in symlists
  584. since they have to be evaluated immediately rather
  585. than each time the property is accessed
  586. The proper fix would be to always create a parse tree
  587. and then convert that one, if appropriate, to a symlist.
  588. Currently, we e.g. don't support any constant expressions
  589. yet either here, while Delphi does.
  590. }
  591. { make sure we don't let constants mask class fields/
  592. methods
  593. }
  594. sym:=nil;
  595. if (not assigned(astruct) or
  596. (search_struct_member(astruct,pattern)=nil)) and
  597. searchsym(pattern,sym,srsymtable) and
  598. (sym.typ = constsym) then
  599. begin
  600. addsymref(sym);
  601. if not is_boolean(tconstsym(sym).constdef) then
  602. Message(parser_e_stored_property_must_be_boolean)
  603. else if (tconstsym(sym).value.valueord=0) then
  604. { same as for _FALSE }
  605. exclude(p.propoptions,ppo_stored)
  606. else
  607. begin
  608. { same as for _TRUE }
  609. { do nothing - ppo_stored is already set to p.propoptions in "include(p.propoptions,ppo_stored);" above }
  610. { especially do not reset the default value - the stored specifier is independent on the default value! }
  611. end;
  612. consume(_ID);
  613. end
  614. else if parse_symlist(p.propaccesslist[palt_stored],def) then
  615. begin
  616. sym:=p.propaccesslist[palt_stored].firstsym^.sym;
  617. case sym.typ of
  618. procsym :
  619. begin
  620. { Create a temporary procvardef to handle parameters }
  621. storedprocdef:=cprocvardef.create(normal_function_level,true);
  622. include(storedprocdef.procoptions,po_methodpointer);
  623. { Return type must be boolean }
  624. storedprocdef.returndef:=pasbool1type;
  625. { Add index parameter if needed }
  626. if ppo_indexed in p.propoptions then
  627. begin
  628. hparavs:=cparavarsym.create('$index',10,vs_value,p.indexdef,[]);
  629. storedprocdef.parast.insertsym(hparavs);
  630. end;
  631. { Insert hidden parameters }
  632. if not assigned(astruct) then
  633. handle_calling_convention(storedprocdef,hcc_default_actions_intf)
  634. else
  635. handle_calling_convention(storedprocdef,hcc_default_actions_intf_struct);
  636. p.propaccesslist[palt_stored].procdef:=Tprocsym(sym).Find_procdef_bypara(storedprocdef.paras,storedprocdef.returndef,[cpo_allowdefaults,cpo_ignorehidden]);
  637. if not assigned(p.propaccesslist[palt_stored].procdef) then
  638. message(parser_e_ill_property_storage_sym);
  639. { Not needed anymore }
  640. storedprocdef.owner.deletedef(storedprocdef);
  641. end;
  642. fieldvarsym :
  643. begin
  644. if not assigned(def) then
  645. internalerror(200310073);
  646. if (ppo_hasparameters in p.propoptions) or
  647. not(is_boolean(def)) then
  648. Message(parser_e_stored_property_must_be_boolean);
  649. end;
  650. else
  651. Message(parser_e_ill_property_access_sym);
  652. end;
  653. end;
  654. end;
  655. end;
  656. end;
  657. end;
  658. if has_implicit_default(p) and not assigned(p.overriddenpropsym) then
  659. begin
  660. p.default:=0;
  661. end;
  662. if not is_record(astruct) and try_to_consume(_DEFAULT) then
  663. begin
  664. if not allow_default_property(p) then
  665. begin
  666. Message(parser_e_property_cant_have_a_default_value);
  667. { Error recovery }
  668. pt:=comp_expr([ef_accept_equal]);
  669. pt.free;
  670. pt := nil;
  671. end
  672. else
  673. begin
  674. { Get the result of the default, the firstpass is
  675. needed to support values like -1 }
  676. pt:=comp_expr([ef_accept_equal]);
  677. if (p.propdef.typ=setdef) and
  678. (pt.nodetype=arrayconstructorn) then
  679. begin
  680. arrayconstructor_to_set(pt);
  681. do_typecheckpass(pt);
  682. end;
  683. inserttypeconv(pt,p.propdef);
  684. if not(is_constnode(pt)) then
  685. Message(parser_e_property_default_value_must_const);
  686. { Set default value }
  687. case pt.nodetype of
  688. setconstn :
  689. p.default:=plongint(tsetconstnode(pt).value_set)^;
  690. ordconstn :
  691. if (Tordconstnode(pt).value<int64(low(longint))) or
  692. (Tordconstnode(pt).value>int64(high(cardinal))) then
  693. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(longint)),tostr(high(cardinal)))
  694. else
  695. p.default:=longint(tordconstnode(pt).value.svalue);
  696. niln :
  697. p.default:=0;
  698. realconstn:
  699. p.default:=longint(single(trealconstnode(pt).value_real));
  700. else if not codegenerror then
  701. internalerror(2019050525);
  702. end;
  703. pt.free;
  704. pt := nil;
  705. end;
  706. end
  707. else if not is_record(astruct) and try_to_consume(_NODEFAULT) then
  708. begin
  709. p.default:=longint($80000000);
  710. end;
  711. (*
  712. else {if allow_default_property(p) then
  713. begin
  714. p.default:=longint($80000000);
  715. end;
  716. *)
  717. { Parse possible "implements" keyword }
  718. if not is_record(astruct) and try_to_consume(_IMPLEMENTS) then
  719. repeat
  720. single_type(def,[]);
  721. if not(is_interface(def)) then
  722. message(parser_e_class_implements_must_be_interface);
  723. if is_interface(p.propdef) then
  724. begin
  725. { an interface type may delegate itself or one of its ancestors }
  726. if not def_is_related(p.propdef,def) then
  727. begin
  728. message2(parser_e_implements_must_have_correct_type,def.typename,p.propdef.typename);
  729. exit;
  730. end;
  731. end
  732. else if is_class(p.propdef) then
  733. begin
  734. ImplIntf:=find_implemented_interface(tobjectdef(p.propdef),tobjectdef(def));
  735. if assigned(ImplIntf) then
  736. begin
  737. if compare_defs(ImplIntf.IntfDef,def,nothingn)<te_equal then
  738. begin
  739. message2(parser_e_implements_must_have_correct_type,ImplIntf.IntfDef.typename,def.typename);
  740. exit;
  741. end;
  742. end
  743. else
  744. begin
  745. message2(parser_e_class_doesnt_implement_interface,p.propdef.typename,def.typename);
  746. exit;
  747. end;
  748. end
  749. else
  750. begin
  751. message(parser_e_implements_must_be_class_or_interface);
  752. exit;
  753. end;
  754. if not assigned(p.propaccesslist[palt_read].firstsym) then
  755. begin
  756. message(parser_e_implements_must_read_specifier);
  757. exit;
  758. end;
  759. if assigned(p.propaccesslist[palt_read].procdef) and
  760. (tprocdef(p.propaccesslist[palt_read].procdef).proccalloption<>pocall_default) then
  761. message(parser_e_implements_getter_not_default_cc);
  762. if assigned(p.propaccesslist[palt_write].firstsym) then
  763. begin
  764. message(parser_e_implements_must_not_have_write_specifier);
  765. exit;
  766. end;
  767. if assigned(p.propaccesslist[palt_stored].firstsym) then
  768. begin
  769. message(parser_e_implements_must_not_have_stored_specifier);
  770. exit;
  771. end;
  772. found:=false;
  773. ImplIntf:=nil;
  774. for i:=0 to tobjectdef(astruct).ImplementedInterfaces.Count-1 do
  775. begin
  776. ImplIntf:=TImplementedInterface(tobjectdef(astruct).ImplementedInterfaces[i]);
  777. if compare_defs(def,ImplIntf.IntfDef,nothingn)>=te_equal then
  778. begin
  779. found:=true;
  780. break;
  781. end;
  782. end;
  783. if found then
  784. begin
  785. { An interface may not be delegated by more than one property,
  786. it also may not have method mappings. }
  787. if Assigned(ImplIntf.ImplementsGetter) then
  788. message1(parser_e_duplicate_implements_clause,ImplIntf.IntfDef.typename);
  789. if Assigned(ImplIntf.NameMappings) then
  790. message2(parser_e_mapping_no_implements,ImplIntf.IntfDef.typename,astruct.objrealname^);
  791. ImplIntf.ImplementsGetter:=p;
  792. ImplIntf.VtblImplIntf:=ImplIntf;
  793. case p.propaccesslist[palt_read].firstsym^.sym.typ of
  794. procsym :
  795. begin
  796. if (po_virtualmethod in tprocdef(p.propaccesslist[palt_read].procdef).procoptions) and
  797. not is_objectpascal_helper(tprocdef(p.propaccesslist[palt_read].procdef).struct) then
  798. ImplIntf.IType:=etVirtualMethodResult
  799. else
  800. ImplIntf.IType:=etStaticMethodResult;
  801. end;
  802. fieldvarsym :
  803. begin
  804. ImplIntf.IType:=etFieldValue;
  805. { this must be done in a more robust way. Can't read the
  806. fieldvarsym's fieldoffset yet, because it may not yet
  807. be set }
  808. ImplIntf.ImplementsField:=p.propaccesslist[palt_read].firstsym^.sym;
  809. end
  810. else
  811. internalerror(200802161);
  812. end;
  813. if not is_interface(p.propdef) then
  814. case ImplIntf.IType of
  815. etVirtualMethodResult: ImplIntf.IType := etVirtualMethodClass;
  816. etStaticMethodResult: ImplIntf.IType := etStaticMethodClass;
  817. etFieldValue: ImplIntf.IType := etFieldValueClass;
  818. else
  819. internalerror(200912101);
  820. end;
  821. end
  822. else
  823. message1(parser_e_implements_uses_non_implemented_interface,def.typename);
  824. until not try_to_consume(_COMMA);
  825. { register propgetter and propsetter procdefs }
  826. if assigned(current_module) and current_module.in_interface then
  827. begin
  828. if readprocdef.proctypeoption=potype_propgetter then
  829. readprocdef.register_def
  830. else
  831. readprocdef.free; // no nil needed
  832. if writeprocdef.proctypeoption=potype_propsetter then
  833. writeprocdef.register_def
  834. else
  835. writeprocdef.free; // no nil needed
  836. end
  837. else
  838. begin
  839. if readprocdef.proctypeoption=potype_propgetter then
  840. readprocdef.maybe_put_in_symtable_stack
  841. else
  842. readprocdef.free; // no nil needed
  843. if writeprocdef.proctypeoption=potype_propsetter then
  844. writeprocdef.maybe_put_in_symtable_stack
  845. else
  846. writeprocdef.free; // no nil needed
  847. end;
  848. result:=p;
  849. end;
  850. function maybe_parse_proc_directives(def:tdef):boolean;
  851. begin
  852. result:=false;
  853. { Process procvar directives before = and ; }
  854. if (
  855. (def.typ=procvardef) or
  856. is_funcref(def)
  857. ) and
  858. (def.typesym=nil) and
  859. check_proc_directive(true) then
  860. begin
  861. parse_proctype_directives(def);
  862. result:=true;
  863. end;
  864. end;
  865. const
  866. variantrecordlevel : longint = 0;
  867. procedure read_public_and_external_sc(sc:TFPObjectList);
  868. var
  869. vs: tabstractvarsym;
  870. begin
  871. { only allowed for one var }
  872. vs:=tabstractvarsym(sc[0]);
  873. if sc.count>1 then
  874. Message1(parser_e_directive_only_one_var,arraytokeninfo[idtoken].str);
  875. read_public_and_external(vs);
  876. end;
  877. procedure read_public_and_external(vs: tabstractvarsym);
  878. var
  879. is_dll,
  880. is_far,
  881. is_cdecl,
  882. is_external_var,
  883. is_weak_external,
  884. is_public_var : boolean;
  885. dll_name,section_name,
  886. C_name,mangledname : string;
  887. begin
  888. { only allowed for one var }
  889. { only allow external and public on global symbols }
  890. if vs.typ<>staticvarsym then
  891. begin
  892. Message(parser_e_no_local_var_external);
  893. exit;
  894. end;
  895. { defaults }
  896. is_dll:=false;
  897. is_far:=false;
  898. is_cdecl:=false;
  899. is_external_var:=false;
  900. is_public_var:=false;
  901. section_name := '';
  902. dll_name := '';
  903. C_name:=vs.realname;
  904. { macpas specific handling due to some switches}
  905. if (m_mac in current_settings.modeswitches) then
  906. begin
  907. if (cs_external_var in current_settings.localswitches) then
  908. begin {The effect of this is the same as if cvar; external; has been given as directives.}
  909. is_cdecl:=true;
  910. is_external_var:=true;
  911. end
  912. else if (cs_externally_visible in current_settings.localswitches) then
  913. begin {The effect of this is the same as if cvar has been given as directives and it's made public.}
  914. is_cdecl:=true;
  915. is_public_var:=true;
  916. end;
  917. end;
  918. { cdecl }
  919. if try_to_consume(_CVAR) then
  920. begin
  921. consume(_SEMICOLON);
  922. is_cdecl:=true;
  923. end;
  924. { external }
  925. is_weak_external:=try_to_consume(_WEAKEXTERNAL);
  926. if is_weak_external or
  927. try_to_consume(_EXTERNAL) then
  928. begin
  929. is_external_var:=true;
  930. { near/far? }
  931. if target_info.system in systems_allow_external_far_var then
  932. begin
  933. if try_to_consume(_FAR) then
  934. is_far:=true
  935. else if try_to_consume(_NEAR) then
  936. is_far:=false;
  937. end;
  938. if (idtoken<>_NAME) and (token<>_SEMICOLON) then
  939. begin
  940. is_dll:=true;
  941. dll_name:=get_stringconst;
  942. if ExtractFileExt(dll_name)='' then
  943. dll_name:=ChangeFileExt(dll_name,target_info.sharedlibext);
  944. end;
  945. if not(is_cdecl) and try_to_consume(_NAME) then
  946. C_name:=get_stringconst;
  947. consume(_SEMICOLON);
  948. end;
  949. { export or public }
  950. if idtoken in [_EXPORT,_PUBLIC] then
  951. begin
  952. consume(_ID);
  953. if is_external_var then
  954. Message(parser_e_not_external_and_export)
  955. else
  956. is_public_var:=true;
  957. if try_to_consume(_NAME) then
  958. C_name:=get_stringconst;
  959. if (target_info.system in systems_allow_section_no_semicolon) and
  960. (vs.typ=staticvarsym) and
  961. try_to_consume (_SECTION) then
  962. section_name:=get_stringconst;
  963. consume(_SEMICOLON);
  964. end;
  965. { Windows uses an indirect reference using import tables }
  966. if is_dll and
  967. (target_info.system in systems_all_windows) then
  968. include(vs.varoptions,vo_is_dll_var);
  969. { This can only happen if vs.typ=staticvarsym }
  970. if section_name<>'' then
  971. begin
  972. tstaticvarsym(vs).section:=section_name;
  973. include(vs.varoptions,vo_has_section);
  974. end;
  975. { Add C _ prefix }
  976. if is_cdecl or
  977. (
  978. is_dll and
  979. (target_info.system in systems_darwin)
  980. ) then
  981. C_Name := target_info.Cprefix+C_Name;
  982. if is_public_var then
  983. begin
  984. include(vs.varoptions,vo_is_public);
  985. vs.varregable := vr_none;
  986. { mark as referenced }
  987. inc(vs.refs);
  988. end;
  989. mangledname:=C_name;
  990. { now we can insert it in the import lib if its a dll, or
  991. add it to the externals }
  992. if is_external_var then
  993. begin
  994. if vo_is_typed_const in vs.varoptions then
  995. Message(parser_e_initialized_not_for_external);
  996. include(vs.varoptions,vo_is_external);
  997. if is_far then
  998. include(vs.varoptions,vo_is_far);
  999. if (is_weak_external) then
  1000. begin
  1001. if not(target_info.system in systems_weak_linking) then
  1002. message(parser_e_weak_external_not_supported);
  1003. include(vs.varoptions,vo_is_weak_external);
  1004. end;
  1005. vs.varregable := vr_none;
  1006. if is_dll then
  1007. begin
  1008. if target_info.system in (systems_all_windows + systems_nativent +
  1009. [system_i386_emx, system_i386_os2]) then
  1010. mangledname:=make_dllmangledname(dll_name,C_name,0,pocall_none);
  1011. current_module.AddExternalImport(dll_name,C_Name,mangledname,0,true,false);
  1012. end
  1013. else
  1014. if tf_has_dllscanner in target_info.flags then
  1015. current_module.dllscannerinputlist.Add(vs.mangledname,vs);
  1016. end;
  1017. { Set the assembler name }
  1018. tstaticvarsym(vs).set_mangledbasename(mangledname);
  1019. tstaticvarsym(vs).set_mangledname(mangledname);
  1020. end;
  1021. procedure try_consume_sectiondirective(var asection: ansistring);
  1022. begin
  1023. if idtoken=_SECTION then
  1024. begin
  1025. consume(_ID);
  1026. asection:=get_stringconst;
  1027. consume(_SEMICOLON);
  1028. end;
  1029. end;
  1030. procedure try_read_field_external(vs: tabstractvarsym);
  1031. var
  1032. extname: string;
  1033. begin
  1034. if try_to_consume(_EXTERNAL) then
  1035. begin
  1036. consume(_NAME);
  1037. extname:=get_stringconst;
  1038. tfieldvarsym(vs).set_externalname(extname);
  1039. consume(_SEMICOLON);
  1040. end;
  1041. end;
  1042. procedure try_read_field_external_sc(sc:TFPObjectList);
  1043. var
  1044. vs: tabstractvarsym;
  1045. begin
  1046. { only allowed for one var }
  1047. vs:=tabstractvarsym(sc[0]);
  1048. if sc.count>1 then
  1049. Message1(parser_e_directive_only_one_var,arraytokeninfo[idtoken].str);
  1050. try_read_field_external(vs);
  1051. end;
  1052. procedure read_var_decls(options:Tvar_dec_options;out had_generic:boolean);
  1053. procedure read_default_value(sc : TFPObjectList);
  1054. var
  1055. vs : tabstractnormalvarsym;
  1056. tcsym : tstaticvarsym;
  1057. templist : tasmlist;
  1058. begin
  1059. vs:=tabstractnormalvarsym(sc[0]);
  1060. if sc.count>1 then
  1061. Message(parser_e_initialized_only_one_var);
  1062. if vo_is_thread_var in vs.varoptions then
  1063. Message(parser_e_initialized_not_for_threadvar);
  1064. consume(_EQ);
  1065. case vs.typ of
  1066. localvarsym :
  1067. begin
  1068. tcsym:=cstaticvarsym.create('$default'+vs.realname,vs_const,vs.vardef,[]);
  1069. include(tcsym.symoptions,sp_internal);
  1070. symtablestack.top.insertsym(tcsym);
  1071. templist:=tasmlist.create;
  1072. read_typed_const(templist,tcsym,false);
  1073. { in case of a generic routine, this initialisation value is not
  1074. used, and will be re-parsed during specialisations (and the
  1075. current version is not type-correct and hence breaks code
  1076. generation for LLVM) }
  1077. if not parse_generic then
  1078. begin
  1079. vs.defaultconstsym:=tcsym;
  1080. current_asmdata.asmlists[al_typedconsts].concatlist(templist);
  1081. end;
  1082. templist.free;
  1083. templist := nil;
  1084. end;
  1085. staticvarsym :
  1086. begin
  1087. maybe_guarantee_record_typesym(vs.vardef,vs.vardef.owner);
  1088. read_typed_const(current_asmdata.asmlists[al_typedconsts],tstaticvarsym(vs),false);
  1089. end;
  1090. else
  1091. internalerror(200611051);
  1092. end;
  1093. vs.varstate:=vs_initialised;
  1094. end;
  1095. {$ifdef gpc_mode}
  1096. procedure read_gpc_name(sc : TFPObjectList);
  1097. var
  1098. vs : tabstractnormalvarsym;
  1099. C_Name : string;
  1100. begin
  1101. consume(_ID);
  1102. C_Name:=get_stringconst;
  1103. vs:=tabstractnormalvarsym(sc[0]);
  1104. if sc.count>1 then
  1105. Message(parser_e_directive_only_one_var,'ABSOLUTE');
  1106. if vs.typ=staticvarsym then
  1107. begin
  1108. tstaticvarsym(vs).set_mangledname(C_Name);
  1109. include(vs.varoptions,vo_is_external);
  1110. end
  1111. else
  1112. Message(parser_e_no_local_var_external);
  1113. end;
  1114. {$endif}
  1115. procedure read_absolute(sc : TFPObjectList);
  1116. var
  1117. vs : tabstractvarsym;
  1118. abssym : tabsolutevarsym;
  1119. pt,hp : tnode;
  1120. st : tsymtable;
  1121. {$if defined(i386) or defined(i8086)}
  1122. tmpaddr : int64;
  1123. {$endif defined(i386) or defined(i8086)}
  1124. begin
  1125. abssym:=nil;
  1126. { only allowed for one var }
  1127. vs:=tabstractvarsym(sc[0]);
  1128. if sc.count>1 then
  1129. Message1(parser_e_directive_only_one_var,'ABSOLUTE');
  1130. if vo_is_typed_const in vs.varoptions then
  1131. Message(parser_e_initialized_not_for_external);
  1132. { parse the rest }
  1133. pt:=expr(true);
  1134. { check allowed absolute types }
  1135. if (pt.nodetype=stringconstn) or
  1136. (is_constcharnode(pt)) then
  1137. begin
  1138. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1139. abssym.fileinfo:=vs.fileinfo;
  1140. if pt.nodetype=stringconstn then
  1141. abssym.asmname:=stringdup(tstringconstnode(pt).asrawbytestring)
  1142. else
  1143. abssym.asmname:=stringdup(chr(tordconstnode(pt).value.svalue));
  1144. abssym.abstyp:=toasm;
  1145. end
  1146. { address }
  1147. else if is_constintnode(pt) then
  1148. begin
  1149. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1150. abssym.fileinfo:=vs.fileinfo;
  1151. abssym.abstyp:=toaddr;
  1152. {$ifndef cpu64bitaddr}
  1153. { on 64 bit systems, abssym.addroffset is a qword and hence this
  1154. test is useless (value is a 64 bit entity) and will always fail
  1155. for positive values (since int64(high(abssym.addroffset))=-1
  1156. }
  1157. if (Tordconstnode(pt).value<int64(low(abssym.addroffset))) or
  1158. (Tordconstnode(pt).value>int64(high(abssym.addroffset))) then
  1159. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1160. else
  1161. {$endif}
  1162. abssym.addroffset:=Tordconstnode(pt).value.svalue;
  1163. {$if defined(i386) or defined(i8086)}
  1164. tcpuabsolutevarsym(abssym).absseg:=false;
  1165. if (target_info.system in [system_i386_go32v2,system_i386_watcom,system_i8086_msdos,system_i8086_win16,system_i8086_embedded]) and
  1166. try_to_consume(_COLON) then
  1167. begin
  1168. pt.free;
  1169. pt:=expr(true);
  1170. if is_constintnode(pt) then
  1171. begin
  1172. {$if defined(i8086)}
  1173. tcpuabsolutevarsym(abssym).addrsegment:=abssym.addroffset;
  1174. tmpaddr:=tordconstnode(pt).value.svalue;
  1175. if (tmpaddr<int64(low(abssym.addroffset))) or
  1176. (tmpaddr>int64(high(abssym.addroffset))) then
  1177. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1178. else
  1179. abssym.addroffset:=tmpaddr;
  1180. {$elseif defined(i386)}
  1181. tmpaddr:=abssym.addroffset shl 4+tordconstnode(pt).value.svalue;
  1182. if (tmpaddr<int64(low(abssym.addroffset))) or
  1183. (tmpaddr>int64(high(abssym.addroffset))) then
  1184. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(abssym.addroffset)),tostr(high(abssym.addroffset)))
  1185. else
  1186. abssym.addroffset:=tmpaddr;
  1187. {$endif}
  1188. tcpuabsolutevarsym(abssym).absseg:=true;
  1189. end
  1190. else
  1191. Message(type_e_ordinal_expr_expected);
  1192. end;
  1193. {$endif i386 or i8086}
  1194. end
  1195. { variable }
  1196. else
  1197. begin
  1198. { we have to be able to take the address of the absolute
  1199. expression
  1200. }
  1201. valid_for_addr(pt,true);
  1202. { remove subscriptn before checking for loadn }
  1203. hp:=pt;
  1204. while (hp.nodetype in [subscriptn,typeconvn,vecn]) do
  1205. begin
  1206. { check for implicit dereferencing and reject it }
  1207. if (hp.nodetype in [subscriptn,vecn]) then
  1208. begin
  1209. if (tunarynode(hp).left.resultdef.typ in [pointerdef,classrefdef]) then
  1210. break;
  1211. { catch, e.g., 'var b: char absolute pchar_var[5];"
  1212. (pchar_var[5] is a pchar_2_string typeconv ->
  1213. the vecn only sees an array of char)
  1214. I don't know if all of these type conversions are
  1215. possible, but they're definitely all bad.
  1216. }
  1217. if (tunarynode(hp).left.nodetype=typeconvn) and
  1218. (ttypeconvnode(tunarynode(hp).left).convtype in
  1219. [tc_pchar_2_string,tc_pointer_2_array,
  1220. tc_intf_2_string,tc_intf_2_guid,
  1221. tc_dynarray_2_variant,tc_interface_2_variant,
  1222. tc_array_2_dynarray]) then
  1223. break;
  1224. if (tunarynode(hp).left.resultdef.typ=stringdef) and
  1225. not(tstringdef(tunarynode(hp).left.resultdef).stringtype in [st_shortstring,st_longstring]) then
  1226. break;
  1227. if (tunarynode(hp).left.resultdef.typ=objectdef) and
  1228. (tobjectdef(tunarynode(hp).left.resultdef).objecttype<>odt_object) then
  1229. break;
  1230. if is_dynamic_array(tunarynode(hp).left.resultdef) then
  1231. break;
  1232. end;
  1233. hp:=tunarynode(hp).left;
  1234. end;
  1235. if (hp.nodetype=loadn) then
  1236. begin
  1237. { we should check the result type of loadn }
  1238. if not (tloadnode(hp).symtableentry.typ in [fieldvarsym,staticvarsym,localvarsym,paravarsym,absolutevarsym]) then
  1239. Message(parser_e_absolute_only_to_var_or_const);
  1240. if vs=tloadnode(hp).symtableentry then
  1241. Message(parser_e_absolute_sym_cannot_reference_itself)
  1242. else
  1243. begin
  1244. abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
  1245. abssym.fileinfo:=vs.fileinfo;
  1246. abssym.abstyp:=tovar;
  1247. abssym.ref:=node_to_propaccesslist(pt);
  1248. end;
  1249. { if the sizes are different, can't be a regvar since you }
  1250. { can't be "absolute upper 8 bits of a register" (except }
  1251. { if its a record field of the same size of a record }
  1252. { regvar, but in that case pt.resultdef.size will have }
  1253. { the same size since it refers to the field and not to }
  1254. { the whole record -- which is why we use pt and not hp) }
  1255. { we can't take the size of an open array or an array of const }
  1256. if is_open_array(pt.resultdef) or
  1257. is_array_of_const(pt.resultdef) or
  1258. (vs.vardef.size <> pt.resultdef.size) then
  1259. make_not_regable(pt,[ra_addr_regable]);
  1260. end
  1261. else
  1262. Message(parser_e_absolute_only_to_var_or_const);
  1263. end;
  1264. pt.free;
  1265. pt := nil;
  1266. { replace old varsym with the new absolutevarsym }
  1267. if assigned(abssym) then
  1268. begin
  1269. st:=vs.owner;
  1270. vs.owner.Deletesym(vs);
  1271. st.insertsym(abssym);
  1272. sc[0]:=abssym;
  1273. end;
  1274. end;
  1275. var
  1276. sc : TFPObjectList;
  1277. vs : tabstractvarsym;
  1278. hdef : tdef;
  1279. i : longint;
  1280. flags : thccflags;
  1281. first,
  1282. isgeneric,
  1283. semicoloneaten,
  1284. allowdefaultvalue,
  1285. hasdefaultvalue : boolean;
  1286. hintsymoptions : tsymoptions;
  1287. deprecatedmsg : pshortstring;
  1288. old_block_type : tblock_type;
  1289. sectionname : ansistring;
  1290. typepos,
  1291. tmp_filepos,
  1292. old_current_filepos : tfileposinfo;
  1293. begin
  1294. old_block_type:=block_type;
  1295. block_type:=bt_var;
  1296. { Force an expected ID error message }
  1297. if not (token in [_ID,_CASE,_END]) then
  1298. consume(_ID);
  1299. { read vars }
  1300. sc:=TFPObjectList.create(false);
  1301. first:=true;
  1302. had_generic:=false;
  1303. vs:=nil;
  1304. fillchar(tmp_filepos,sizeof(tmp_filepos),0);
  1305. while (token=_ID) do
  1306. begin
  1307. semicoloneaten:=false;
  1308. hasdefaultvalue:=false;
  1309. allowdefaultvalue:=true;
  1310. sc.clear;
  1311. repeat
  1312. if (token = _ID) then
  1313. begin
  1314. isgeneric:=(vd_check_generic in options) and
  1315. not (m_delphi in current_settings.modeswitches) and
  1316. (idtoken=_GENERIC);
  1317. case symtablestack.top.symtabletype of
  1318. localsymtable :
  1319. vs:=clocalvarsym.create(orgpattern,vs_value,generrordef,[]);
  1320. staticsymtable,
  1321. globalsymtable :
  1322. begin
  1323. vs:=cstaticvarsym.create(orgpattern,vs_value,generrordef,[]);
  1324. if vd_threadvar in options then
  1325. include(vs.varoptions,vo_is_thread_var);
  1326. end;
  1327. else
  1328. internalerror(200411064);
  1329. end;
  1330. sc.add(vs);
  1331. if isgeneric then
  1332. tmp_filepos:=current_filepos;
  1333. end
  1334. else
  1335. isgeneric:=false;
  1336. consume(_ID);
  1337. { when the first variable had been read the next declaration could be
  1338. a "generic procedure", "generic function" or
  1339. "generic class (function/procedure)" }
  1340. if not first
  1341. and isgeneric
  1342. and (sc.count=1)
  1343. and (token in [_PROCEDURE,_FUNCTION,_CLASS]) then
  1344. begin
  1345. vs.free;
  1346. vs := nil;
  1347. sc.clear;
  1348. had_generic:=true;
  1349. break;
  1350. end
  1351. else
  1352. begin
  1353. vs.register_sym;
  1354. if isgeneric then
  1355. begin
  1356. { ensure correct error position }
  1357. old_current_filepos:=current_filepos;
  1358. current_filepos:=tmp_filepos;
  1359. symtablestack.top.insertsym(vs);
  1360. current_filepos:=old_current_filepos;
  1361. end
  1362. else
  1363. symtablestack.top.insertsym(vs);
  1364. end;
  1365. until not try_to_consume(_COMMA);
  1366. if had_generic then
  1367. break;
  1368. { read variable type def }
  1369. block_type:=bt_var_type;
  1370. consume(_COLON);
  1371. typepos:=current_tokenpos;
  1372. {$ifdef gpc_mode}
  1373. if (m_gpc in current_settings.modeswitches) and
  1374. (token=_ID) and
  1375. (orgpattern='__asmname__') then
  1376. read_gpc_name(sc);
  1377. {$endif}
  1378. read_anon_type(hdef,false,nil);
  1379. maybe_guarantee_record_typesym(hdef,symtablestack.top);
  1380. for i:=0 to sc.count-1 do
  1381. begin
  1382. vs:=tabstractvarsym(sc[i]);
  1383. vs.vardef:=hdef;
  1384. end;
  1385. block_type:=bt_var;
  1386. { Process procvar directives }
  1387. if maybe_parse_proc_directives(hdef) then
  1388. semicoloneaten:=true;
  1389. { check for absolute }
  1390. if try_to_consume(_ABSOLUTE) then
  1391. begin
  1392. read_absolute(sc);
  1393. allowdefaultvalue:=false;
  1394. end;
  1395. { Check for EXTERNAL etc directives before a semicolon }
  1396. if (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) or (idtoken = _WEAKEXTERNAL) then
  1397. begin
  1398. read_public_and_external_sc(sc);
  1399. allowdefaultvalue:=false;
  1400. semicoloneaten:=true;
  1401. end;
  1402. { try to parse the hint directives }
  1403. hintsymoptions:=[];
  1404. deprecatedmsg:=nil;
  1405. try_consume_hintdirective(hintsymoptions,deprecatedmsg);
  1406. for i:=0 to sc.count-1 do
  1407. begin
  1408. vs:=tabstractvarsym(sc[i]);
  1409. vs.symoptions := vs.symoptions + hintsymoptions;
  1410. if deprecatedmsg<>nil then
  1411. vs.deprecatedmsg:=stringdup(deprecatedmsg^);
  1412. end;
  1413. stringdispose(deprecatedmsg);
  1414. { Handling of Delphi typed const = initialized vars }
  1415. if allowdefaultvalue and
  1416. (token=_EQ) and
  1417. not(m_tp7 in current_settings.modeswitches) and
  1418. (symtablestack.top.symtabletype<>parasymtable) then
  1419. begin
  1420. { Add calling convention for procvar }
  1421. if (
  1422. (hdef.typ=procvardef) or
  1423. is_funcref(hdef)
  1424. ) and
  1425. (hdef.typesym=nil) then
  1426. begin
  1427. if po_is_function_ref in tprocvardef(hdef).procoptions then
  1428. begin
  1429. if not (m_function_references in current_settings.modeswitches) and
  1430. not (po_is_block in tprocvardef(hdef).procoptions) then
  1431. messagepos(typepos,sym_e_error_in_type_def)
  1432. else
  1433. begin
  1434. if adjust_funcref(hdef,nil,nil) then
  1435. { the def was changed, so update it }
  1436. for i:=0 to sc.count-1 do
  1437. begin
  1438. vs:=tabstractvarsym(sc[i]);
  1439. vs.vardef:=hdef;
  1440. end;
  1441. if current_scanner.replay_stack_depth=0 then
  1442. hdef.register_def;
  1443. end;
  1444. end;
  1445. handle_calling_convention(hdef,hcc_default_actions_intf);
  1446. end;
  1447. read_default_value(sc);
  1448. hasdefaultvalue:=true;
  1449. end
  1450. else
  1451. begin
  1452. if not(semicoloneaten) then
  1453. consume(_SEMICOLON);
  1454. end;
  1455. { Support calling convention for procvars after semicolon }
  1456. if not(hasdefaultvalue) and
  1457. (
  1458. (hdef.typ=procvardef) or
  1459. is_funcref(hdef)
  1460. ) and
  1461. (hdef.typesym=nil) then
  1462. begin
  1463. { Parse procvar directives after ; }
  1464. maybe_parse_proc_directives(hdef);
  1465. if (hdef.typ=procvardef) and (po_is_function_ref in tprocvardef(hdef).procoptions) then
  1466. begin
  1467. if not (m_function_references in current_settings.modeswitches) and
  1468. not (po_is_block in tprocvardef(hdef).procoptions) then
  1469. messagepos(typepos,sym_e_error_in_type_def)
  1470. else
  1471. begin
  1472. if adjust_funcref(hdef,nil,nil) then
  1473. { the def was changed, so update it }
  1474. for i:=0 to sc.count-1 do
  1475. begin
  1476. vs:=tabstractvarsym(sc[i]);
  1477. vs.vardef:=hdef;
  1478. end;
  1479. if current_scanner.replay_stack_depth=0 then
  1480. hdef.register_def;
  1481. end;
  1482. end;
  1483. { Add calling convention for procvar }
  1484. if hdef.typ=procvardef then
  1485. flags:=hcc_default_actions_intf
  1486. else
  1487. flags:=hcc_default_actions_intf_struct;
  1488. handle_calling_convention(hdef,flags);
  1489. { Handling of Delphi typed const = initialized vars }
  1490. if (token=_EQ) and
  1491. not(m_tp7 in current_settings.modeswitches) and
  1492. (symtablestack.top.symtabletype<>parasymtable) then
  1493. begin
  1494. read_default_value(sc);
  1495. hasdefaultvalue:=true;
  1496. end;
  1497. end;
  1498. { Check for EXTERNAL etc directives or, in macpas, if cs_external_var is set}
  1499. if (
  1500. (
  1501. ((idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) or (idtoken = _WEAKEXTERNAL)) and
  1502. (m_cvar_support in current_settings.modeswitches)
  1503. ) or
  1504. (
  1505. (m_mac in current_settings.modeswitches) and
  1506. (
  1507. (cs_external_var in current_settings.localswitches) or
  1508. (cs_externally_visible in current_settings.localswitches)
  1509. )
  1510. )
  1511. ) then
  1512. read_public_and_external_sc(sc);
  1513. { try to parse a section directive }
  1514. if (target_info.system in systems_allow_section) and
  1515. (symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) and
  1516. (idtoken=_SECTION) then
  1517. begin
  1518. try_consume_sectiondirective(sectionname);
  1519. if sectionname<>'' then
  1520. begin
  1521. for i:=0 to sc.count-1 do
  1522. begin
  1523. vs:=tabstractvarsym(sc[i]);
  1524. if (vs.varoptions *[vo_is_external,vo_is_weak_external])<>[] then
  1525. Message(parser_e_externals_no_section);
  1526. if vs.typ<>staticvarsym then
  1527. Message(parser_e_section_no_locals);
  1528. tstaticvarsym(vs).section:=sectionname;
  1529. include(vs.varoptions, vo_has_section);
  1530. end;
  1531. end;
  1532. end;
  1533. { allocate normal variable (non-external and non-typed-const) staticvarsyms }
  1534. for i:=0 to sc.count-1 do
  1535. begin
  1536. vs:=tabstractvarsym(sc[i]);
  1537. if (vs.typ=staticvarsym) and
  1538. not(vo_is_typed_const in vs.varoptions) and
  1539. not(vo_is_external in vs.varoptions) then
  1540. cnodeutils.insertbssdata(tstaticvarsym(vs));
  1541. if vo_is_public in vs.varoptions then
  1542. current_module.add_public_asmsym(vs.mangledname,AB_GLOBAL,AT_DATA);
  1543. end;
  1544. first:=false;
  1545. end;
  1546. block_type:=old_block_type;
  1547. { free the list }
  1548. sc.free;
  1549. sc := nil;
  1550. end;
  1551. function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
  1552. var
  1553. stowner,tmpdef : tdef;
  1554. st : tsymtable;
  1555. begin
  1556. result:=true;
  1557. st:=symtablestack.top;
  1558. if not (st.symtabletype in [recordsymtable,objectsymtable]) then
  1559. exit;
  1560. stowner:=tdef(st.defowner);
  1561. while assigned(stowner) and (stowner.typ in [objectdef,recorddef]) do
  1562. begin
  1563. if def.typ=arraydef then
  1564. begin
  1565. tmpdef:=def;
  1566. while (tmpdef.typ=arraydef) do
  1567. begin
  1568. { dynamic arrays are allowed in certain cases }
  1569. if allowdynarray and (ado_IsDynamicArray in tarraydef(tmpdef).arrayoptions) then
  1570. begin
  1571. tmpdef:=nil;
  1572. break;
  1573. end;
  1574. tmpdef:=tarraydef(tmpdef).elementdef;
  1575. end;
  1576. end
  1577. else
  1578. tmpdef:=def;
  1579. if assigned(tmpdef) and
  1580. (is_object(tmpdef) or is_record(tmpdef)) and
  1581. is_owned_by(tabstractrecorddef(stowner),tabstractrecorddef(tmpdef)) then
  1582. begin
  1583. Message1(type_e_type_is_not_completly_defined,tabstractrecorddef(tmpdef).RttiName);
  1584. result:=false;
  1585. break;
  1586. end;
  1587. stowner:=tdef(stowner.owner.defowner);
  1588. end;
  1589. end;
  1590. procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean; out attr_element_count : integer);
  1591. var
  1592. sc : TFPObjectList;
  1593. i : longint;
  1594. hs,sorg : string;
  1595. gendef,hdef,casetype : tdef;
  1596. { maxsize contains the max. size of a variant }
  1597. { startvarrec contains the start of the variant part of a record }
  1598. maxsize, startvarrecsize : asizeint;
  1599. usedalign,
  1600. maxalignment,startvarrecalign,
  1601. maxpadalign, startpadalign: shortint;
  1602. pt : tnode;
  1603. fieldvs : tfieldvarsym;
  1604. hstaticvs : tstaticvarsym;
  1605. vs : tabstractvarsym;
  1606. srsym : tsym;
  1607. srsymtable : TSymtable;
  1608. visibility : tvisibility;
  1609. recst : tabstractrecordsymtable;
  1610. unionsymtable : trecordsymtable;
  1611. offset : longint;
  1612. uniondef : trecorddef;
  1613. hintsymoptions : tsymoptions;
  1614. deprecatedmsg : pshortstring;
  1615. hadgendummy,
  1616. semicoloneaten,
  1617. removeclassoption: boolean;
  1618. dummyattrelementcount : integer;
  1619. {$if defined(powerpc) or defined(powerpc64)}
  1620. tempdef: tdef;
  1621. is_first_type: boolean;
  1622. {$endif powerpc or powerpc64}
  1623. old_block_type: tblock_type;
  1624. typepos : tfileposinfo;
  1625. begin
  1626. old_block_type:=block_type;
  1627. block_type:=bt_var;
  1628. recst:=tabstractrecordsymtable(symtablestack.top);
  1629. {$if defined(powerpc) or defined(powerpc64)}
  1630. is_first_type:=true;
  1631. {$endif powerpc or powerpc64}
  1632. { Force an expected ID error message }
  1633. if not (token in [_ID,_CASE,_END]) then
  1634. consume(_ID);
  1635. { read vars }
  1636. sc:=TFPObjectList.create(false);
  1637. removeclassoption:=false;
  1638. had_generic:=false;
  1639. attr_element_count:=0;
  1640. while (token=_ID) and
  1641. not(((vd_object in options) or
  1642. ((vd_record in options) and (m_advanced_records in current_settings.modeswitches))) and
  1643. ((idtoken in [_PUBLIC,_PRIVATE,_PUBLISHED,_PROTECTED,_STRICT]) or
  1644. ((m_final_fields in current_settings.modeswitches) and
  1645. (idtoken=_FINAL)))) do
  1646. begin
  1647. visibility:=symtablestack.top.currentvisibility;
  1648. semicoloneaten:=false;
  1649. sc.clear;
  1650. repeat
  1651. sorg:=orgpattern;
  1652. if token=_ID then
  1653. begin
  1654. vs:=cfieldvarsym.create(sorg,vs_value,generrordef,[]);
  1655. { normally the visibility is set via addfield, but sometimes
  1656. we collect symbols so we can add them in a batch of
  1657. potentially mixed visibility, and then the individual
  1658. symbols need to have their visibility already set }
  1659. vs.visibility:=visibility;
  1660. if (vd_check_generic in options) and (idtoken=_GENERIC) then
  1661. had_generic:=true;
  1662. end
  1663. else
  1664. vs:=nil;
  1665. consume(_ID);
  1666. if assigned(vs) and
  1667. (
  1668. not had_generic or
  1669. not (token in [_PROCEDURE,_FUNCTION,_CLASS])
  1670. ) then
  1671. begin
  1672. vs.register_sym;
  1673. sc.add(vs);
  1674. recst.insertsym(vs);
  1675. had_generic:=false;
  1676. end
  1677. else
  1678. vs.free; // no nil needed
  1679. until not try_to_consume(_COMMA);
  1680. if m_delphi in current_settings.modeswitches then
  1681. block_type:=bt_var_type
  1682. else
  1683. block_type:=old_block_type;
  1684. if had_generic and (sc.count=0) then
  1685. break;
  1686. consume(_COLON);
  1687. if attr_element_count=0 then
  1688. attr_element_count:=sc.Count;
  1689. typepos:=current_filepos;
  1690. { make sure that the correct genericdef is set up, especially if
  1691. we're dealing with anonymous type declarations }
  1692. gendef:=nil;
  1693. if df_specialization in current_structdef.defoptions then
  1694. begin
  1695. srsymtable:=current_structdef.genericdef.getsymtable(gs_record);
  1696. if not assigned(srsymtable) then
  1697. internalerror(2024041204);
  1698. srsym:=tsym(srsymtable.find(tabstractvarsym(sc[0]).name));
  1699. if not assigned(srsym) then
  1700. internalerror(2024041205);
  1701. if srsym.typ<>fieldvarsym then
  1702. internalerror(2024041206);
  1703. gendef:=tfieldvarsym(srsym).vardef;
  1704. end;
  1705. read_anon_type(hdef,false,tstoreddef(gendef));
  1706. maybe_guarantee_record_typesym(hdef,symtablestack.top);
  1707. {$ifdef wasm}
  1708. if is_wasm_reference_type(hdef) then
  1709. messagepos(typepos,sym_e_wasm_ref_types_cannot_be_used_in_records);
  1710. {$endif wasm}
  1711. block_type:=bt_var;
  1712. { allow only static fields reference to struct where they are declared }
  1713. if not (vd_class in options) then
  1714. begin
  1715. if not check_allowed_for_var_or_const(hdef,true) then
  1716. { for error recovery or compiler will crash later }
  1717. hdef:=generrordef;
  1718. end;
  1719. { field type is a generic param so set a flag in the struct }
  1720. if assigned(hdef.typesym) and (sp_generic_para in hdef.typesym.symoptions) then
  1721. include(current_structdef.defoptions,df_has_generic_fields);
  1722. { Process procvar directives }
  1723. if maybe_parse_proc_directives(hdef) then
  1724. semicoloneaten:=true;
  1725. {$if defined(powerpc) or defined(powerpc64)}
  1726. { from gcc/gcc/config/rs6000/rs6000.h:
  1727. /* APPLE LOCAL begin Macintosh alignment 2002-1-22 ff */
  1728. /* Return the alignment of a struct based on the Macintosh PowerPC
  1729. alignment rules. In general the alignment of a struct is
  1730. determined by the greatest alignment of its elements. However, the
  1731. PowerPC rules cause the alignment of a struct to peg at word
  1732. alignment except when the first field has greater than word
  1733. (32-bit) alignment, in which case the alignment is determined by
  1734. the alignment of the first field. */
  1735. }
  1736. { TODO: check whether this is also for AIX }
  1737. if (target_info.abi in [abi_powerpc_aix,abi_powerpc_darwin]) and
  1738. is_first_type and
  1739. (symtablestack.top.symtabletype=recordsymtable) and
  1740. (trecordsymtable(symtablestack.top).usefieldalignment=C_alignment) then
  1741. begin
  1742. tempdef:=hdef;
  1743. while tempdef.typ=arraydef do
  1744. tempdef:=tarraydef(tempdef).elementdef;
  1745. if tempdef.typ<>recorddef then
  1746. maxpadalign:=tempdef.alignment
  1747. else
  1748. maxpadalign:=trecorddef(tempdef).padalignment;
  1749. if (maxpadalign>4) and
  1750. (maxpadalign>trecordsymtable(symtablestack.top).padalignment) then
  1751. trecordsymtable(symtablestack.top).padalignment:=maxpadalign;
  1752. is_first_type:=false;
  1753. end;
  1754. {$endif powerpc or powerpc64}
  1755. { types that use init/final are not allowed in variant parts, but
  1756. classes are allowed }
  1757. if (variantrecordlevel>0) then
  1758. if is_managed_type(hdef) then
  1759. Message(parser_e_cant_use_inittable_here);
  1760. { try to parse the hint directives }
  1761. hintsymoptions:=[];
  1762. deprecatedmsg:=nil;
  1763. try_consume_hintdirective(hintsymoptions,deprecatedmsg);
  1764. { update variable type and hints }
  1765. for i:=0 to sc.count-1 do
  1766. begin
  1767. fieldvs:=tfieldvarsym(sc[i]);
  1768. fieldvs.vardef:=hdef;
  1769. { insert any additional hint directives }
  1770. fieldvs.symoptions := fieldvs.symoptions + hintsymoptions;
  1771. if deprecatedmsg<>nil then
  1772. fieldvs.deprecatedmsg:=stringdup(deprecatedmsg^);
  1773. end;
  1774. stringdispose(deprecatedmsg);
  1775. { Records and objects can't have default values }
  1776. { for a record there doesn't need to be a ; before the END or ) }
  1777. if not(token in [_END,_RKLAMMER]) and
  1778. not(semicoloneaten) then
  1779. consume(_SEMICOLON);
  1780. { Parse procvar directives after ; }
  1781. maybe_parse_proc_directives(hdef);
  1782. { Add calling convention for procvar }
  1783. if (
  1784. (hdef.typ=procvardef) or
  1785. is_funcref(hdef)
  1786. ) and (hdef.typesym=nil) then
  1787. begin
  1788. if (hdef.typ=procvardef) and (po_is_function_ref in tprocvardef(hdef).procoptions) then
  1789. begin
  1790. if not (m_function_references in current_settings.modeswitches) and
  1791. not (po_is_block in tprocvardef(hdef).procoptions) then
  1792. messagepos(typepos,sym_e_error_in_type_def)
  1793. else
  1794. begin
  1795. if adjust_funcref(hdef,nil,nil) then
  1796. { the def was changed, so update it }
  1797. for i:=0 to sc.count-1 do
  1798. begin
  1799. fieldvs:=tfieldvarsym(sc[i]);
  1800. fieldvs.vardef:=hdef;
  1801. end;
  1802. if current_scanner.replay_stack_depth=0 then
  1803. hdef.register_def;
  1804. end;
  1805. end;
  1806. handle_calling_convention(hdef,hcc_default_actions_intf);
  1807. end;
  1808. if (vd_object in options) then
  1809. begin
  1810. { if it is not a class var section and token=STATIC then it is a class field too }
  1811. if not (vd_class in options) and try_to_consume(_STATIC) then
  1812. begin
  1813. consume(_SEMICOLON);
  1814. include(options,vd_class);
  1815. removeclassoption:=true;
  1816. end;
  1817. { Fields in Java classes/interfaces can have a separately
  1818. specified external name }
  1819. if is_java_class_or_interface(tdef(recst.defowner)) and
  1820. (oo_is_external in tobjectdef(recst.defowner).objectoptions) then
  1821. try_read_field_external_sc(sc);
  1822. end;
  1823. if (visibility=vis_published) and
  1824. not(is_class(hdef)) then
  1825. begin
  1826. MessagePos(tfieldvarsym(sc[0]).fileinfo,parser_e_cant_publish_that);
  1827. visibility:=vis_public;
  1828. end;
  1829. if (visibility=vis_published) and
  1830. not(oo_can_have_published in tobjectdef(hdef).objectoptions) and
  1831. not(m_delphi in current_settings.modeswitches) then
  1832. begin
  1833. MessagePos(tfieldvarsym(sc[0]).fileinfo,parser_e_only_publishable_classes_can_be_published);
  1834. visibility:=vis_public;
  1835. end;
  1836. if vd_class in options then
  1837. begin
  1838. { add static flag and staticvarsyms }
  1839. for i:=0 to sc.count-1 do
  1840. begin
  1841. fieldvs:=tfieldvarsym(sc[i]);
  1842. fieldvs.visibility:=visibility;
  1843. hstaticvs:=make_field_static(recst,fieldvs);
  1844. if vd_threadvar in options then
  1845. include(hstaticvs.varoptions,vo_is_thread_var);
  1846. if not parse_generic then
  1847. cnodeutils.insertbssdata(hstaticvs);
  1848. if vd_final in options then
  1849. hstaticvs.varspez:=vs_final;
  1850. end;
  1851. if removeclassoption then
  1852. begin
  1853. exclude(options,vd_class);
  1854. removeclassoption:=false;
  1855. end;
  1856. end;
  1857. if vd_final in options then
  1858. begin
  1859. { add final flag }
  1860. for i:=0 to sc.count-1 do
  1861. begin
  1862. fieldvs:=tfieldvarsym(sc[i]);
  1863. fieldvs.varspez:=vs_final;
  1864. end;
  1865. end;
  1866. if not(vd_canreorder in options) then
  1867. { add field(s) to the recordsymtable }
  1868. recst.addfieldlist(sc,false)
  1869. else
  1870. { we may reorder the fields before adding them to the symbol
  1871. table }
  1872. reorderlist.concatlistcopy(sc)
  1873. end;
  1874. if m_delphi in current_settings.modeswitches then
  1875. block_type:=bt_var_type
  1876. else
  1877. block_type:=old_block_type;
  1878. { Check for Case }
  1879. if (vd_record in options) and
  1880. try_to_consume(_CASE) then
  1881. begin
  1882. maxsize:=0;
  1883. maxalignment:=0;
  1884. maxpadalign:=0;
  1885. { already inside a variant record? if not, setup a new variantdesc chain }
  1886. if not(assigned(variantdesc)) then
  1887. variantdesc:=@trecorddef(trecordsymtable(recst).defowner).variantrecdesc;
  1888. { else just concat the info to the given one }
  1889. new(variantdesc^);
  1890. fillchar(variantdesc^^,sizeof(tvariantrecdesc),0);
  1891. { including a field declaration? }
  1892. fieldvs:=nil;
  1893. if token=_ID then
  1894. begin
  1895. sorg:=orgpattern;
  1896. hs:=pattern;
  1897. searchsym(hs,srsym,srsymtable);
  1898. if not(assigned(srsym) and (srsym.typ in [typesym,unitsym])) then
  1899. begin
  1900. consume(_ID);
  1901. consume(_COLON);
  1902. fieldvs:=cfieldvarsym.create(sorg,vs_value,generrordef,[]);
  1903. variantdesc^^.variantselector:=fieldvs;
  1904. symtablestack.top.insertsym(fieldvs);
  1905. end;
  1906. end;
  1907. read_anon_type(casetype,true,nil);
  1908. block_type:=bt_var;
  1909. if assigned(fieldvs) then
  1910. begin
  1911. fieldvs.vardef:=casetype;
  1912. recst.addfield(fieldvs,recst.currentvisibility);
  1913. end;
  1914. if not(is_ordinal(casetype))
  1915. {$ifndef cpu64bitaddr}
  1916. or is_64bitint(casetype)
  1917. {$endif cpu64bitaddr}
  1918. then
  1919. Message(type_e_ordinal_expr_expected);
  1920. consume(_OF);
  1921. UnionSymtable:=trecordsymtable.create('',current_settings.packrecords,current_settings.alignment.recordalignmin);
  1922. UnionDef:=crecorddef.create('',unionsymtable);
  1923. uniondef.isunion:=true;
  1924. startvarrecsize:=UnionSymtable.datasize;
  1925. { align the bitpacking to the next byte }
  1926. UnionSymtable.datasize:=startvarrecsize;
  1927. startvarrecalign:=UnionSymtable.fieldalignment;
  1928. startpadalign:=Unionsymtable.padalignment;
  1929. symtablestack.push(UnionSymtable);
  1930. repeat
  1931. SetLength(variantdesc^^.branches,length(variantdesc^^.branches)+1);
  1932. fillchar(variantdesc^^.branches[high(variantdesc^^.branches)],
  1933. sizeof(variantdesc^^.branches[high(variantdesc^^.branches)]),0);
  1934. repeat
  1935. pt:=comp_expr([ef_accept_equal]);
  1936. if not(pt.nodetype=ordconstn) then
  1937. Message(parser_e_illegal_expression);
  1938. inserttypeconv(pt,casetype);
  1939. { iso pascal does not support ranges in variant record definitions }
  1940. if (([m_iso,m_extpas]*current_settings.modeswitches)=[]) and try_to_consume(_POINTPOINT) then
  1941. pt:=crangenode.create(pt,comp_expr([ef_accept_equal]))
  1942. else
  1943. begin
  1944. with variantdesc^^.branches[high(variantdesc^^.branches)] do
  1945. begin
  1946. SetLength(values,length(values)+1);
  1947. values[high(values)]:=tordconstnode(pt).value;
  1948. end;
  1949. end;
  1950. pt.free;
  1951. pt := nil;
  1952. if token=_COMMA then
  1953. consume(_COMMA)
  1954. else
  1955. break;
  1956. until false;
  1957. if m_delphi in current_settings.modeswitches then
  1958. block_type:=bt_var_type
  1959. else
  1960. block_type:=old_block_type;
  1961. consume(_COLON);
  1962. { read the vars }
  1963. consume(_LKLAMMER);
  1964. inc(variantrecordlevel);
  1965. if token<>_RKLAMMER then
  1966. read_record_fields([vd_record],nil,@variantdesc^^.branches[high(variantdesc^^.branches)].nestedvariant,hadgendummy,dummyattrelementcount);
  1967. dec(variantrecordlevel);
  1968. consume(_RKLAMMER);
  1969. { calculates maximal variant size }
  1970. maxsize:=max(maxsize,unionsymtable.datasize);
  1971. maxalignment:=max(maxalignment,unionsymtable.fieldalignment);
  1972. maxpadalign:=max(maxpadalign,unionsymtable.padalignment);
  1973. { the items of the next variant are overlayed }
  1974. unionsymtable.datasize:=startvarrecsize;
  1975. unionsymtable.fieldalignment:=startvarrecalign;
  1976. unionsymtable.padalignment:=startpadalign;
  1977. if (token<>_END) and (token<>_RKLAMMER) then
  1978. consume(_SEMICOLON)
  1979. else
  1980. break;
  1981. until (token=_END) or (token=_RKLAMMER);
  1982. symtablestack.pop(UnionSymtable);
  1983. { at last set the record size to that of the biggest variant }
  1984. unionsymtable.datasize:=maxsize;
  1985. unionsymtable.fieldalignment:=maxalignment;
  1986. unionsymtable.addalignmentpadding;
  1987. {$if defined(powerpc) or defined(powerpc64)}
  1988. { parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
  1989. if (target_info.system in [system_powerpc_darwin, system_powerpc_macosclassic, system_powerpc64_darwin]) and
  1990. is_first_type and
  1991. (recst.usefieldalignment=C_alignment) and
  1992. (maxpadalign>recst.padalignment) then
  1993. recst.padalignment:=maxpadalign;
  1994. {$endif powerpc or powerpc64}
  1995. { Align the offset where the union symtable is added }
  1996. case recst.usefieldalignment of
  1997. { allow the unionsymtable to be aligned however it wants }
  1998. { (within the global min/max limits) }
  1999. 0, { default }
  2000. C_alignment:
  2001. usedalign:=used_align(unionsymtable.recordalignment,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
  2002. { 1 byte alignment if we are bitpacked }
  2003. bit_alignment:
  2004. usedalign:=1;
  2005. mac68k_alignment:
  2006. usedalign:=2;
  2007. { otherwise alignment at the packrecords alignment of the }
  2008. { current record }
  2009. else
  2010. usedalign:=used_align(recst.fieldalignment,current_settings.alignment.recordalignmin,current_settings.alignment.recordalignmax);
  2011. end;
  2012. offset:=align(recst.datasize,usedalign);
  2013. recst.datasize:=offset+unionsymtable.datasize;
  2014. if unionsymtable.recordalignment>recst.fieldalignment then
  2015. recst.fieldalignment:=unionsymtable.recordalignment;
  2016. if unionsymtable.explicitrecordalignment>recst.explicitrecordalignment then
  2017. recst.explicitrecordalignment:=unionsymtable.explicitrecordalignment;
  2018. trecordsymtable(recst).insertunionst(Unionsymtable,offset);
  2019. uniondef.owner.deletedef(uniondef);
  2020. end;
  2021. { free the list }
  2022. sc.free;
  2023. sc := nil;
  2024. {$ifdef powerpc}
  2025. is_first_type := false;
  2026. {$endif powerpc}
  2027. block_type:=old_block_type;
  2028. end;
  2029. end.