symtable.pas 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  3. This unit handles the symbol tables
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit symtable;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,cclasses,
  23. { global }
  24. cpuinfo,globtype,tokens,
  25. { symtable }
  26. symconst,symbase,symtype,symdef,symsym,
  27. { ppu }
  28. ppu,
  29. { assembler }
  30. aasmtai,aasmdata
  31. ;
  32. {****************************************************************************
  33. Symtable types
  34. ****************************************************************************}
  35. type
  36. tstoredsymtable = class(TSymtable)
  37. private
  38. b_needs_init_final : boolean;
  39. procedure _needs_init_final(sym:TObject;arg:pointer);
  40. procedure check_forward(sym:TObject;arg:pointer);
  41. procedure labeldefined(sym:TObject;arg:pointer);
  42. procedure varsymbolused(sym:TObject;arg:pointer);
  43. procedure TestPrivate(sym:TObject;arg:pointer);
  44. procedure objectprivatesymbolused(sym:TObject;arg:pointer);
  45. procedure loaddefs(ppufile:tcompilerppufile);
  46. procedure loadsyms(ppufile:tcompilerppufile);
  47. procedure writedefs(ppufile:tcompilerppufile);
  48. procedure writesyms(ppufile:tcompilerppufile);
  49. public
  50. procedure insert(sym:TSymEntry;checkdup:boolean=true);override;
  51. procedure delete(sym:TSymEntry);override;
  52. { load/write }
  53. procedure ppuload(ppufile:tcompilerppufile);virtual;
  54. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  55. procedure buildderef;virtual;
  56. procedure buildderefimpl;virtual;
  57. procedure deref;virtual;
  58. procedure derefimpl;virtual;
  59. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  60. procedure allsymbolsused;
  61. procedure allprivatesused;
  62. procedure check_forwards;
  63. procedure checklabels;
  64. function needs_init_final : boolean;
  65. procedure testfordefaultproperty(sym:TObject;arg:pointer);
  66. end;
  67. tabstractrecordsymtable = class(tstoredsymtable)
  68. public
  69. usefieldalignment, { alignment to use for fields (PACKRECORDS value), C_alignment is C style }
  70. recordalignment, { alignment desired when inserting this record }
  71. fieldalignment, { alignment current alignment used when fields are inserted }
  72. padalignment : shortint; { size to a multiple of which the symtable has to be rounded up }
  73. constructor create(const n:string;usealign:shortint);
  74. procedure ppuload(ppufile:tcompilerppufile);override;
  75. procedure ppuwrite(ppufile:tcompilerppufile);override;
  76. procedure alignrecord(fieldoffset:aint;varalign:shortint);
  77. procedure addfield(sym:tfieldvarsym;vis:tvisibility);
  78. procedure addalignmentpadding;
  79. procedure insertdef(def:TDefEntry);override;
  80. function is_packed: boolean;
  81. function has_single_field(out sym:tfieldvarsym): boolean;
  82. function get_unit_symtable: tsymtable;
  83. protected
  84. _datasize : aint;
  85. { size in bits of the data in case of bitpacked record. Only important during construction, }
  86. { no need to save in/restore from ppu file. datasize is always (databitsize+7) div 8. }
  87. databitsize : aint;
  88. procedure setdatasize(val: aint);
  89. public
  90. function iscurrentunit: boolean; override;
  91. property datasize : aint read _datasize write setdatasize;
  92. end;
  93. trecordsymtable = class(tabstractrecordsymtable)
  94. public
  95. constructor create(const n:string;usealign:shortint);
  96. procedure insertunionst(unionst : trecordsymtable;offset : longint);
  97. end;
  98. tObjectSymtable = class(tabstractrecordsymtable)
  99. public
  100. constructor create(adefowner:tdef;const n:string;usealign:shortint);
  101. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  102. end;
  103. { tabstractlocalsymtable }
  104. tabstractlocalsymtable = class(tstoredsymtable)
  105. public
  106. procedure ppuwrite(ppufile:tcompilerppufile);override;
  107. function count_locals:longint;
  108. end;
  109. tlocalsymtable = class(tabstractlocalsymtable)
  110. public
  111. constructor create(adefowner:tdef;level:byte);
  112. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  113. end;
  114. { tparasymtable }
  115. tparasymtable = class(tabstractlocalsymtable)
  116. public
  117. readonly: boolean;
  118. constructor create(adefowner:tdef;level:byte);
  119. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  120. procedure insertdef(def:TDefEntry);override;
  121. end;
  122. tabstractuniTSymtable = class(tstoredsymtable)
  123. public
  124. constructor create(const n : string;id:word);
  125. function iscurrentunit:boolean;override;
  126. end;
  127. tglobalsymtable = class(tabstractuniTSymtable)
  128. public
  129. unittypecount : word;
  130. constructor create(const n : string;id:word);
  131. procedure ppuload(ppufile:tcompilerppufile);override;
  132. procedure ppuwrite(ppufile:tcompilerppufile);override;
  133. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  134. end;
  135. tstaticsymtable = class(tabstractuniTSymtable)
  136. public
  137. constructor create(const n : string;id:word);
  138. procedure ppuload(ppufile:tcompilerppufile);override;
  139. procedure ppuwrite(ppufile:tcompilerppufile);override;
  140. function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
  141. end;
  142. twithsymtable = class(TSymtable)
  143. withrefnode : tobject; { tnode }
  144. constructor create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  145. destructor destroy;override;
  146. procedure clear;override;
  147. procedure insertdef(def:TDefEntry);override;
  148. end;
  149. tstt_excepTSymtable = class(TSymtable)
  150. public
  151. constructor create;
  152. end;
  153. tmacrosymtable = class(tstoredsymtable)
  154. public
  155. constructor create(exported: boolean);
  156. end;
  157. { tenumsymtable }
  158. tenumsymtable = class(tstoredsymtable)
  159. public
  160. procedure insert(sym: TSymEntry; checkdup: boolean = true); override;
  161. constructor create(adefowner:tdef);
  162. end;
  163. { tarraysymtable }
  164. tarraysymtable = class(tstoredsymtable)
  165. public
  166. procedure insertdef(def:TDefEntry);override;
  167. constructor create(adefowner:tdef);
  168. end;
  169. var
  170. systemunit : tglobalsymtable; { pointer to the system unit }
  171. {****************************************************************************
  172. Functions
  173. ****************************************************************************}
  174. {*** Misc ***}
  175. function FullTypeName(def,otherdef:tdef):string;
  176. function generate_nested_name(symtable:tsymtable;delimiter:string):string;
  177. procedure incompatibletypes(def1,def2:tdef);
  178. procedure hidesym(sym:TSymEntry);
  179. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  180. {*** Search ***}
  181. procedure addsymref(sym:tsym);
  182. function is_owned_by(childdef,ownerdef:tabstractrecorddef):boolean;
  183. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
  184. function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
  185. function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
  186. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  187. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  188. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  189. function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
  190. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  191. function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  192. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  193. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  194. function search_system_type(const s: TIDString): ttypesym;
  195. function search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
  196. function search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
  197. function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
  198. function search_enumerator_operator(from_def,to_def:Tdef):Tprocdef;
  199. function search_last_objectpascal_classhelper(pd : tobjectdef;out odef : tobjectdef):boolean;
  200. function search_objectpascal_class_helper(pd,contextclassh : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  201. function search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  202. function search_objc_method(const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  203. {Looks for macro s (must be given in upper case) in the macrosymbolstack, }
  204. {and returns it if found. Returns nil otherwise.}
  205. function search_macro(const s : string):tsym;
  206. { Additionally to searching for a macro, also checks whether it's still }
  207. { actually defined (could be disable using "undef") }
  208. function defined_macro(const s : string):boolean;
  209. {*** Object Helpers ***}
  210. function search_default_property(pd : tobjectdef) : tpropertysym;
  211. function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
  212. {*** Macro Helpers ***}
  213. {If called initially, the following procedures manipulate macros in }
  214. {initialmacrotable, otherwise they manipulate system macros local to a module.}
  215. {Name can be given in any case (it will be converted to upper case).}
  216. procedure def_system_macro(const name : string);
  217. procedure set_system_macro(const name, value : string);
  218. procedure set_system_compvar(const name, value : string);
  219. procedure undef_system_macro(const name : string);
  220. {*** symtable stack ***}
  221. { $ifdef DEBUG
  222. procedure test_symtablestack;
  223. procedure list_symtablestack;
  224. $endif DEBUG}
  225. {$ifdef UNITALIASES}
  226. type
  227. punit_alias = ^tunit_alias;
  228. tunit_alias = object(TNamedIndexItem)
  229. newname : pshortstring;
  230. constructor init(const n:string);
  231. destructor done;virtual;
  232. end;
  233. var
  234. unitaliases : pdictionary;
  235. procedure addunitalias(const n:string);
  236. function getunitalias(const n:string):string;
  237. {$endif UNITALIASES}
  238. {*** Init / Done ***}
  239. procedure IniTSymtable;
  240. procedure DoneSymtable;
  241. const
  242. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] = (
  243. { NOTOKEN } 'error',
  244. { _PLUS } 'plus',
  245. { _MINUS } 'minus',
  246. { _STAR } 'star',
  247. { _SLASH } 'slash',
  248. { _EQ } 'equal',
  249. { _GT } 'greater',
  250. { _LT } 'lower',
  251. { _GTE } 'greater_or_equal',
  252. { _LTE } 'lower_or_equal',
  253. { _NE } 'not_equal',
  254. { _SYMDIF } 'sym_diff',
  255. { _STARSTAR } 'starstar',
  256. { _OP_AS } 'as',
  257. { _OP_IN } 'in',
  258. { _OP_IS } 'is',
  259. { _OP_OR } 'or',
  260. { _OP_AND } 'and',
  261. { _OP_DIV } 'div',
  262. { _OP_MOD } 'mod',
  263. { _OP_NOT } 'not',
  264. { _OP_SHL } 'shl',
  265. { _OP_SHR } 'shr',
  266. { _OP_XOR } 'xor',
  267. { _ASSIGNMENT } 'assign',
  268. { _OP_EXPLICIT } 'explicit',
  269. { _OP_ENUMERATOR } 'enumerator',
  270. { _OP_INC } 'inc',
  271. { _OP_DEC } 'dec');
  272. implementation
  273. uses
  274. { global }
  275. verbose,globals,
  276. { target }
  277. systems,
  278. { symtable }
  279. symutil,defcmp,defutil,
  280. { module }
  281. fmodule,
  282. { codegen }
  283. procinfo
  284. ;
  285. var
  286. dupnr : longint; { unique number for duplicate symbols }
  287. {*****************************************************************************
  288. TStoredSymtable
  289. *****************************************************************************}
  290. procedure tstoredsymtable.insert(sym:TSymEntry;checkdup:boolean=true);
  291. begin
  292. inherited insert(sym,checkdup);
  293. end;
  294. procedure tstoredsymtable.delete(sym:TSymEntry);
  295. begin
  296. inherited delete(sym);
  297. end;
  298. procedure tstoredsymtable.ppuload(ppufile:tcompilerppufile);
  299. begin
  300. { load the table's flags }
  301. if ppufile.readentry<>ibsymtableoptions then
  302. Message(unit_f_ppu_read_error);
  303. ppufile.getsmallset(tableoptions);
  304. { load definitions }
  305. loaddefs(ppufile);
  306. { load symbols }
  307. loadsyms(ppufile);
  308. end;
  309. procedure tstoredsymtable.ppuwrite(ppufile:tcompilerppufile);
  310. begin
  311. { write the table's flags }
  312. ppufile.putsmallset(tableoptions);
  313. ppufile.writeentry(ibsymtableoptions);
  314. { write definitions }
  315. writedefs(ppufile);
  316. { write symbols }
  317. writesyms(ppufile);
  318. end;
  319. procedure tstoredsymtable.loaddefs(ppufile:tcompilerppufile);
  320. var
  321. def : tdef;
  322. b : byte;
  323. begin
  324. { load start of definition section, which holds the amount of defs }
  325. if ppufile.readentry<>ibstartdefs then
  326. Message(unit_f_ppu_read_error);
  327. { read definitions }
  328. repeat
  329. b:=ppufile.readentry;
  330. case b of
  331. ibpointerdef : def:=tpointerdef.ppuload(ppufile);
  332. ibarraydef : def:=tarraydef.ppuload(ppufile);
  333. iborddef : def:=torddef.ppuload(ppufile);
  334. ibfloatdef : def:=tfloatdef.ppuload(ppufile);
  335. ibprocdef : def:=tprocdef.ppuload(ppufile);
  336. ibshortstringdef : def:=tstringdef.loadshort(ppufile);
  337. iblongstringdef : def:=tstringdef.loadlong(ppufile);
  338. ibansistringdef : def:=tstringdef.loadansi(ppufile);
  339. ibwidestringdef : def:=tstringdef.loadwide(ppufile);
  340. ibunicodestringdef : def:=tstringdef.loadunicode(ppufile);
  341. ibrecorddef : def:=trecorddef.ppuload(ppufile);
  342. ibobjectdef : def:=tobjectdef.ppuload(ppufile);
  343. ibenumdef : def:=tenumdef.ppuload(ppufile);
  344. ibsetdef : def:=tsetdef.ppuload(ppufile);
  345. ibprocvardef : def:=tprocvardef.ppuload(ppufile);
  346. ibfiledef : def:=tfiledef.ppuload(ppufile);
  347. ibclassrefdef : def:=tclassrefdef.ppuload(ppufile);
  348. ibformaldef : def:=tformaldef.ppuload(ppufile);
  349. ibvariantdef : def:=tvariantdef.ppuload(ppufile);
  350. ibundefineddef : def:=tundefineddef.ppuload(ppufile);
  351. ibenddefs : break;
  352. ibend : Message(unit_f_ppu_read_error);
  353. else
  354. Message1(unit_f_ppu_invalid_entry,tostr(b));
  355. end;
  356. InsertDef(def);
  357. until false;
  358. end;
  359. procedure tstoredsymtable.loadsyms(ppufile:tcompilerppufile);
  360. var
  361. b : byte;
  362. sym : tsym;
  363. begin
  364. { load start of definition section, which holds the amount of defs }
  365. if ppufile.readentry<>ibstartsyms then
  366. Message(unit_f_ppu_read_error);
  367. { now read the symbols }
  368. repeat
  369. b:=ppufile.readentry;
  370. case b of
  371. ibtypesym : sym:=ttypesym.ppuload(ppufile);
  372. ibprocsym : sym:=tprocsym.ppuload(ppufile);
  373. ibconstsym : sym:=tconstsym.ppuload(ppufile);
  374. ibstaticvarsym : sym:=tstaticvarsym.ppuload(ppufile);
  375. iblocalvarsym : sym:=tlocalvarsym.ppuload(ppufile);
  376. ibparavarsym : sym:=tparavarsym.ppuload(ppufile);
  377. ibfieldvarsym : sym:=tfieldvarsym.ppuload(ppufile);
  378. ibabsolutevarsym : sym:=tabsolutevarsym.ppuload(ppufile);
  379. ibenumsym : sym:=tenumsym.ppuload(ppufile);
  380. ibpropertysym : sym:=tpropertysym.ppuload(ppufile);
  381. ibunitsym : sym:=tunitsym.ppuload(ppufile);
  382. iblabelsym : sym:=tlabelsym.ppuload(ppufile);
  383. ibsyssym : sym:=tsyssym.ppuload(ppufile);
  384. ibmacrosym : sym:=tmacro.ppuload(ppufile);
  385. ibendsyms : break;
  386. ibend : Message(unit_f_ppu_read_error);
  387. else
  388. Message1(unit_f_ppu_invalid_entry,tostr(b));
  389. end;
  390. Insert(sym,false);
  391. until false;
  392. end;
  393. procedure tstoredsymtable.writedefs(ppufile:tcompilerppufile);
  394. var
  395. i : longint;
  396. def : tstoreddef;
  397. begin
  398. { each definition get a number, write then the amount of defs to the
  399. ibstartdef entry }
  400. ppufile.putlongint(DefList.count);
  401. ppufile.writeentry(ibstartdefs);
  402. { now write the definition }
  403. for i:=0 to DefList.Count-1 do
  404. begin
  405. def:=tstoreddef(DefList[i]);
  406. def.ppuwrite(ppufile);
  407. end;
  408. { write end of definitions }
  409. ppufile.writeentry(ibenddefs);
  410. end;
  411. procedure tstoredsymtable.writesyms(ppufile:tcompilerppufile);
  412. var
  413. i : longint;
  414. sym : Tstoredsym;
  415. begin
  416. { each definition get a number, write then the amount of syms and the
  417. datasize to the ibsymdef entry }
  418. ppufile.putlongint(SymList.count);
  419. ppufile.writeentry(ibstartsyms);
  420. { foreach is used to write all symbols }
  421. for i:=0 to SymList.Count-1 do
  422. begin
  423. sym:=tstoredsym(SymList[i]);
  424. sym.ppuwrite(ppufile);
  425. end;
  426. { end of symbols }
  427. ppufile.writeentry(ibendsyms);
  428. end;
  429. procedure tstoredsymtable.buildderef;
  430. var
  431. i : longint;
  432. def : tstoreddef;
  433. sym : tstoredsym;
  434. begin
  435. { interface definitions }
  436. for i:=0 to DefList.Count-1 do
  437. begin
  438. def:=tstoreddef(DefList[i]);
  439. def.buildderef;
  440. end;
  441. { interface symbols }
  442. for i:=0 to SymList.Count-1 do
  443. begin
  444. sym:=tstoredsym(SymList[i]);
  445. sym.buildderef;
  446. end;
  447. end;
  448. procedure tstoredsymtable.buildderefimpl;
  449. var
  450. i : longint;
  451. def : tstoreddef;
  452. begin
  453. { implementation definitions }
  454. for i:=0 to DefList.Count-1 do
  455. begin
  456. def:=tstoreddef(DefList[i]);
  457. def.buildderefimpl;
  458. end;
  459. end;
  460. procedure tstoredsymtable.deref;
  461. var
  462. i : longint;
  463. def : tstoreddef;
  464. sym : tstoredsym;
  465. begin
  466. { first deref the interface ttype symbols. This is needs
  467. to be done before the interface defs are derefed, because
  468. the interface defs can contain references to the type symbols
  469. which then already need to contain a resolved typedef field (PFV) }
  470. for i:=0 to SymList.Count-1 do
  471. begin
  472. sym:=tstoredsym(SymList[i]);
  473. if sym.typ=typesym then
  474. sym.deref;
  475. end;
  476. { interface definitions }
  477. for i:=0 to DefList.Count-1 do
  478. begin
  479. def:=tstoreddef(DefList[i]);
  480. def.deref;
  481. end;
  482. { interface symbols }
  483. for i:=0 to SymList.Count-1 do
  484. begin
  485. sym:=tstoredsym(SymList[i]);
  486. if sym.typ<>typesym then
  487. sym.deref;
  488. end;
  489. end;
  490. procedure tstoredsymtable.derefimpl;
  491. var
  492. i : longint;
  493. def : tstoreddef;
  494. begin
  495. { implementation definitions }
  496. for i:=0 to DefList.Count-1 do
  497. begin
  498. def:=tstoreddef(DefList[i]);
  499. def.derefimpl;
  500. end;
  501. end;
  502. function tstoredsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  503. var
  504. hsym : tsym;
  505. begin
  506. hsym:=tsym(FindWithHash(hashedid));
  507. if assigned(hsym) then
  508. DuplicateSym(hashedid,sym,hsym);
  509. result:=assigned(hsym);
  510. end;
  511. {**************************************
  512. Callbacks
  513. **************************************}
  514. procedure TStoredSymtable.check_forward(sym:TObject;arg:pointer);
  515. begin
  516. if tsym(sym).typ=procsym then
  517. tprocsym(sym).check_forward
  518. { check also object method table }
  519. { we needn't to test the def list }
  520. { because each object has to have a type sym,
  521. only test objects declarations, not type renamings }
  522. else
  523. if (tsym(sym).typ=typesym) and
  524. assigned(ttypesym(sym).typedef) and
  525. (ttypesym(sym).typedef.typesym=ttypesym(sym)) and
  526. (ttypesym(sym).typedef.typ in [objectdef,recorddef]) then
  527. tabstractrecorddef(ttypesym(sym).typedef).check_forwards;
  528. end;
  529. procedure TStoredSymtable.labeldefined(sym:TObject;arg:pointer);
  530. begin
  531. if (tsym(sym).typ=labelsym) and
  532. not(tlabelsym(sym).defined) then
  533. begin
  534. if tlabelsym(sym).used then
  535. Message1(sym_e_label_used_and_not_defined,tlabelsym(sym).realname)
  536. else
  537. Message1(sym_w_label_not_defined,tlabelsym(sym).realname);
  538. end;
  539. end;
  540. procedure TStoredSymtable.varsymbolused(sym:TObject;arg:pointer);
  541. begin
  542. if (tsym(sym).typ in [staticvarsym,localvarsym,paravarsym,fieldvarsym]) and
  543. ((tsym(sym).owner.symtabletype in
  544. [parasymtable,localsymtable,ObjectSymtable,recordsymtable,staticsymtable])) then
  545. begin
  546. { unused symbol should be reported only if no }
  547. { error is reported }
  548. { if the symbol is in a register it is used }
  549. { also don't count the value parameters which have local copies }
  550. { also don't claim for high param of open parameters (PM) }
  551. if (Errorcount<>0) or
  552. ([vo_is_hidden_para,vo_is_funcret] * tabstractvarsym(sym).varoptions = [vo_is_hidden_para]) or
  553. (sp_internal in tsym(sym).symoptions) then
  554. exit;
  555. if (tstoredsym(sym).refs=0) then
  556. begin
  557. if (vo_is_funcret in tabstractvarsym(sym).varoptions) then
  558. begin
  559. { don't warn about the result of constructors }
  560. if ((tsym(sym).owner.symtabletype<>localsymtable) or
  561. (tprocdef(tsym(sym).owner.defowner).proctypeoption<>potype_constructor)) and
  562. not(cs_opt_nodedfa in current_settings.optimizerswitches) then
  563. MessagePos(tsym(sym).fileinfo,sym_w_function_result_not_set)
  564. end
  565. else if (tsym(sym).owner.symtabletype=parasymtable) then
  566. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_not_used,tsym(sym).prettyname)
  567. else if (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  568. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname)
  569. else
  570. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_not_used,tsym(sym).prettyname);
  571. end
  572. else if tabstractvarsym(sym).varstate in [vs_written,vs_initialised] then
  573. begin
  574. if (tsym(sym).owner.symtabletype=parasymtable) then
  575. begin
  576. if not(tabstractvarsym(sym).varspez in [vs_var,vs_out,vs_constref]) and
  577. not(vo_is_funcret in tabstractvarsym(sym).varoptions) then
  578. MessagePos1(tsym(sym).fileinfo,sym_h_para_identifier_only_set,tsym(sym).prettyname)
  579. end
  580. else if (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  581. MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_only_set,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname)
  582. else if tabstractvarsym(sym).varoptions*[vo_is_funcret,vo_is_public,vo_is_external]=[] then
  583. MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_only_set,tsym(sym).prettyname);
  584. end
  585. else if (tabstractvarsym(sym).varstate = vs_read_not_warned) and
  586. ([vo_is_public,vo_is_external] * tabstractvarsym(sym).varoptions = []) then
  587. MessagePos1(tsym(sym).fileinfo,sym_w_identifier_only_read,tsym(sym).prettyname)
  588. end
  589. else if ((tsym(sym).owner.symtabletype in
  590. [ObjectSymtable,parasymtable,localsymtable,staticsymtable,recordsymtable])) then
  591. begin
  592. if (Errorcount<>0) or
  593. (sp_internal in tsym(sym).symoptions) then
  594. exit;
  595. { do not claim for inherited private fields !! }
  596. if (tsym(sym).refs=0) and (tsym(sym).owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  597. case tsym(sym).typ of
  598. typesym:
  599. MessagePos2(tsym(sym).fileinfo,sym_n_private_type_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  600. constsym:
  601. MessagePos2(tsym(sym).fileinfo,sym_n_private_const_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  602. propertysym:
  603. MessagePos2(tsym(sym).fileinfo,sym_n_private_property_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  604. else
  605. MessagePos2(tsym(sym).fileinfo,sym_n_private_method_not_used,tabstractrecorddef(tsym(sym).owner.defowner).RttiName,tsym(sym).prettyname);
  606. end
  607. { units references are problematic }
  608. else
  609. begin
  610. if (tsym(sym).refs=0) and
  611. not(tsym(sym).typ in [enumsym,unitsym]) and
  612. not(is_funcret_sym(tsym(sym))) and
  613. { don't complain about compiler generated syms for specializations, see also #13405 }
  614. not((tsym(sym).typ=typesym) and (df_specialization in ttypesym(sym).typedef.defoptions) and
  615. (pos('$',ttypesym(sym).Realname)<>0)) and
  616. (
  617. (tsym(sym).typ<>procsym) or
  618. ((tsym(sym).owner.symtabletype=staticsymtable) and
  619. not current_module.is_unit)
  620. ) and
  621. { don't complain about alias for hidden _cmd parameter to
  622. obj-c methods }
  623. not((tsym(sym).typ in [localvarsym,paravarsym,absolutevarsym]) and
  624. (vo_is_msgsel in tabstractvarsym(sym).varoptions)) then
  625. MessagePos2(tsym(sym).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(sym).typ],tsym(sym).prettyname);
  626. end;
  627. end;
  628. end;
  629. procedure TStoredSymtable.TestPrivate(sym:TObject;arg:pointer);
  630. begin
  631. if tsym(sym).visibility in [vis_private,vis_strictprivate] then
  632. varsymbolused(sym,arg);
  633. end;
  634. procedure TStoredSymtable.objectprivatesymbolused(sym:TObject;arg:pointer);
  635. begin
  636. {
  637. Don't test simple object aliases PM
  638. }
  639. if (tsym(sym).typ=typesym) and
  640. (ttypesym(sym).typedef.typ in [objectdef,recorddef]) and
  641. (ttypesym(sym).typedef.typesym=tsym(sym)) then
  642. tabstractrecorddef(ttypesym(sym).typedef).symtable.SymList.ForEachCall(@TestPrivate,nil);
  643. end;
  644. procedure tstoredsymtable.testfordefaultproperty(sym:TObject;arg:pointer);
  645. begin
  646. if (tsym(sym).typ=propertysym) and
  647. (ppo_defaultproperty in tpropertysym(sym).propoptions) then
  648. ppointer(arg)^:=sym;
  649. end;
  650. {***********************************************
  651. Process all entries
  652. ***********************************************}
  653. { checks, if all procsyms and methods are defined }
  654. procedure tstoredsymtable.check_forwards;
  655. begin
  656. SymList.ForEachCall(@check_forward,nil);
  657. end;
  658. procedure tstoredsymtable.checklabels;
  659. begin
  660. SymList.ForEachCall(@labeldefined,nil);
  661. end;
  662. procedure tstoredsymtable.allsymbolsused;
  663. begin
  664. SymList.ForEachCall(@varsymbolused,nil);
  665. end;
  666. procedure tstoredsymtable.allprivatesused;
  667. begin
  668. SymList.ForEachCall(@objectprivatesymbolused,nil);
  669. end;
  670. procedure TStoredSymtable._needs_init_final(sym:TObject;arg:pointer);
  671. begin
  672. if b_needs_init_final then
  673. exit;
  674. { don't check static symbols - they can be present in structures only and
  675. always have a reference to a symbol defined on unit level }
  676. if sp_static in tsym(sym).symoptions then
  677. exit;
  678. case tsym(sym).typ of
  679. fieldvarsym,
  680. staticvarsym,
  681. localvarsym,
  682. paravarsym :
  683. begin
  684. if is_managed_type(tabstractvarsym(sym).vardef) then
  685. b_needs_init_final:=true;
  686. end;
  687. end;
  688. end;
  689. { returns true, if p contains data which needs init/final code }
  690. function tstoredsymtable.needs_init_final : boolean;
  691. begin
  692. b_needs_init_final:=false;
  693. SymList.ForEachCall(@_needs_init_final,nil);
  694. needs_init_final:=b_needs_init_final;
  695. end;
  696. {****************************************************************************
  697. TAbstractRecordSymtable
  698. ****************************************************************************}
  699. constructor tabstractrecordsymtable.create(const n:string;usealign:shortint);
  700. begin
  701. inherited create(n);
  702. moduleid:=current_module.moduleid;
  703. _datasize:=0;
  704. databitsize:=0;
  705. recordalignment:=1;
  706. usefieldalignment:=usealign;
  707. padalignment:=1;
  708. { recordalign C_alignment means C record packing, that starts
  709. with an alignment of 1 }
  710. case usealign of
  711. C_alignment,
  712. bit_alignment:
  713. fieldalignment:=1;
  714. mac68k_alignment:
  715. fieldalignment:=2;
  716. else
  717. fieldalignment:=usealign;
  718. end;
  719. end;
  720. procedure tabstractrecordsymtable.ppuload(ppufile:tcompilerppufile);
  721. begin
  722. inherited ppuload(ppufile);
  723. end;
  724. procedure tabstractrecordsymtable.ppuwrite(ppufile:tcompilerppufile);
  725. var
  726. oldtyp : byte;
  727. begin
  728. oldtyp:=ppufile.entrytyp;
  729. ppufile.entrytyp:=subentryid;
  730. inherited ppuwrite(ppufile);
  731. ppufile.entrytyp:=oldtyp;
  732. end;
  733. function field2recordalignment(fieldoffs, fieldalign: aint): aint;
  734. begin
  735. { optimal alignment of the record when declaring a variable of this }
  736. { type is independent of the packrecords setting }
  737. if (fieldoffs mod fieldalign) = 0 then
  738. result:=fieldalign
  739. else if (fieldalign >= 16) and
  740. ((fieldoffs mod 16) = 0) and
  741. ((fieldalign mod 16) = 0) then
  742. result:=16
  743. else if (fieldalign >= 8) and
  744. ((fieldoffs mod 8) = 0) and
  745. ((fieldalign mod 8) = 0) then
  746. result:=8
  747. else if (fieldalign >= 4) and
  748. ((fieldoffs mod 4) = 0) and
  749. ((fieldalign mod 4) = 0) then
  750. result:=4
  751. else if (fieldalign >= 2) and
  752. ((fieldoffs mod 2) = 0) and
  753. ((fieldalign mod 2) = 0) then
  754. result:=2
  755. else
  756. result:=1;
  757. end;
  758. procedure tabstractrecordsymtable.alignrecord(fieldoffset:aint;varalign:shortint);
  759. var
  760. varalignrecord: shortint;
  761. begin
  762. case usefieldalignment of
  763. C_alignment:
  764. varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
  765. mac68k_alignment:
  766. varalignrecord:=2;
  767. else
  768. varalignrecord:=field2recordalignment(fieldoffset,varalign);
  769. end;
  770. recordalignment:=max(recordalignment,varalignrecord);
  771. end;
  772. procedure tabstractrecordsymtable.addfield(sym:tfieldvarsym;vis:tvisibility);
  773. var
  774. l : aint;
  775. varalignfield,
  776. varalign : shortint;
  777. vardef : tdef;
  778. begin
  779. if (sym.owner<>self) then
  780. internalerror(200602031);
  781. if sym.fieldoffset<>-1 then
  782. internalerror(200602032);
  783. { set visibility for the symbol }
  784. sym.visibility:=vis;
  785. { this symbol can't be loaded to a register }
  786. sym.varregable:=vr_none;
  787. { Calculate field offset }
  788. l:=sym.getsize;
  789. vardef:=sym.vardef;
  790. varalign:=vardef.alignment;
  791. case usefieldalignment of
  792. bit_alignment:
  793. begin
  794. { bitpacking only happens for ordinals, the rest is aligned at }
  795. { 1 byte (compatible with GPC/GCC) }
  796. if is_ordinal(vardef) then
  797. begin
  798. sym.fieldoffset:=databitsize;
  799. l:=sym.getpackedbitsize;
  800. end
  801. else
  802. begin
  803. databitsize:=_datasize*8;
  804. sym.fieldoffset:=databitsize;
  805. if (l>high(aint) div 8) then
  806. Message(sym_e_segment_too_large);
  807. l:=l*8;
  808. end;
  809. if varalign=0 then
  810. varalign:=size_2_align(l);
  811. recordalignment:=max(recordalignment,field2recordalignment(databitsize mod 8,varalign));
  812. { bit packed records are limited to high(aint) bits }
  813. { instead of bytes to avoid double precision }
  814. { arithmetic in offset calculations }
  815. if int64(l)>high(aint)-sym.fieldoffset then
  816. begin
  817. Message(sym_e_segment_too_large);
  818. _datasize:=high(aint);
  819. databitsize:=high(aint);
  820. end
  821. else
  822. begin
  823. databitsize:=sym.fieldoffset+l;
  824. _datasize:=(databitsize+7) div 8;
  825. end;
  826. { rest is not applicable }
  827. exit;
  828. end;
  829. { Calc the alignment size for C style records }
  830. C_alignment:
  831. begin
  832. if (varalign>4) and
  833. ((varalign mod 4)<>0) and
  834. (vardef.typ=arraydef) then
  835. Message1(sym_w_wrong_C_pack,vardef.typename);
  836. if varalign=0 then
  837. varalign:=l;
  838. if (fieldalignment<current_settings.alignment.maxCrecordalign) then
  839. begin
  840. if (varalign>16) and (fieldalignment<32) then
  841. fieldalignment:=32
  842. else if (varalign>12) and (fieldalignment<16) then
  843. fieldalignment:=16
  844. { 12 is needed for long double }
  845. else if (varalign>8) and (fieldalignment<12) then
  846. fieldalignment:=12
  847. else if (varalign>4) and (fieldalignment<8) then
  848. fieldalignment:=8
  849. else if (varalign>2) and (fieldalignment<4) then
  850. fieldalignment:=4
  851. else if (varalign>1) and (fieldalignment<2) then
  852. fieldalignment:=2;
  853. end;
  854. fieldalignment:=min(fieldalignment,current_settings.alignment.maxCrecordalign);
  855. end;
  856. mac68k_alignment:
  857. begin
  858. { mac68k alignment (C description):
  859. * char is aligned to 1 byte
  860. * everything else (except vector) is aligned to 2 bytes
  861. * vector is aligned to 16 bytes
  862. }
  863. if l>1 then
  864. fieldalignment:=2
  865. else
  866. fieldalignment:=1;
  867. varalign:=2;
  868. end;
  869. end;
  870. if varalign=0 then
  871. varalign:=size_2_align(l);
  872. varalignfield:=used_align(varalign,current_settings.alignment.recordalignmin,fieldalignment);
  873. sym.fieldoffset:=align(_datasize,varalignfield);
  874. if l>high(aint)-sym.fieldoffset then
  875. begin
  876. Message(sym_e_segment_too_large);
  877. _datasize:=high(aint);
  878. end
  879. else
  880. _datasize:=sym.fieldoffset+l;
  881. { Calc alignment needed for this record }
  882. alignrecord(sym.fieldoffset,varalign);
  883. end;
  884. procedure tabstractrecordsymtable.addalignmentpadding;
  885. begin
  886. { make the record size aligned correctly so it can be
  887. used as elements in an array. For C records we
  888. use the fieldalignment, because that is updated with the
  889. used alignment. }
  890. if (padalignment = 1) then
  891. case usefieldalignment of
  892. C_alignment:
  893. padalignment:=fieldalignment;
  894. { bitpacked }
  895. bit_alignment:
  896. padalignment:=1;
  897. { mac68k: always round to multiple of 2 }
  898. mac68k_alignment:
  899. padalignment:=2;
  900. { default/no packrecords specified }
  901. 0:
  902. padalignment:=recordalignment
  903. { specific packrecords setting -> use as upper limit }
  904. else
  905. padalignment:=min(recordalignment,usefieldalignment);
  906. end;
  907. _datasize:=align(_datasize,padalignment);
  908. end;
  909. procedure tabstractrecordsymtable.insertdef(def:TDefEntry);
  910. begin
  911. { Enums must also be available outside the record scope,
  912. insert in the owner of this symtable }
  913. if def.typ=enumdef then
  914. defowner.owner.insertdef(def)
  915. else
  916. inherited insertdef(def);
  917. end;
  918. function tabstractrecordsymtable.is_packed: boolean;
  919. begin
  920. result:=usefieldalignment=bit_alignment;
  921. end;
  922. function tabstractrecordsymtable.has_single_field(out sym: tfieldvarsym): boolean;
  923. var
  924. i: longint;
  925. begin
  926. result:=false;
  927. { If a record contains a union, it does not contain a "single
  928. non-composite field" in the context of certain ABIs requiring
  929. special treatment for such records }
  930. if (defowner.typ=recorddef) and
  931. trecorddef(defowner).isunion then
  932. exit;
  933. { a record/object can contain other things than fields }
  934. for i:=0 to SymList.Count-1 do
  935. begin
  936. if tsym(symlist[i]).typ=fieldvarsym then
  937. begin
  938. if result then
  939. begin
  940. result:=false;
  941. exit;
  942. end;
  943. result:=true;
  944. sym:=tfieldvarsym(symlist[i])
  945. end;
  946. end;
  947. end;
  948. function tabstractrecordsymtable.get_unit_symtable: tsymtable;
  949. begin
  950. result:=defowner.owner;
  951. while assigned(result) and (result.symtabletype in [ObjectSymtable,recordsymtable]) do
  952. result:=result.defowner.owner;
  953. end;
  954. procedure tabstractrecordsymtable.setdatasize(val: aint);
  955. begin
  956. _datasize:=val;
  957. if (usefieldalignment=bit_alignment) then
  958. { can overflow in non bitpacked records }
  959. databitsize:=val*8;
  960. end;
  961. function tabstractrecordsymtable.iscurrentunit: boolean;
  962. begin
  963. Result := Assigned(current_module) and (current_module.moduleid=moduleid);
  964. end;
  965. {****************************************************************************
  966. TRecordSymtable
  967. ****************************************************************************}
  968. constructor trecordsymtable.create(const n:string;usealign:shortint);
  969. begin
  970. inherited create(n,usealign);
  971. symtabletype:=recordsymtable;
  972. end;
  973. { this procedure is reserved for inserting case variant into
  974. a record symtable }
  975. { the offset is the location of the start of the variant
  976. and datasize and dataalignment corresponds to
  977. the complete size (see code in pdecl unit) PM }
  978. procedure trecordsymtable.insertunionst(unionst : trecordsymtable;offset : longint);
  979. var
  980. sym : tsym;
  981. def : tdef;
  982. i : integer;
  983. varalignrecord,varalign,
  984. storesize,storealign : aint;
  985. bitsize: aint;
  986. begin
  987. storesize:=_datasize;
  988. storealign:=fieldalignment;
  989. _datasize:=offset;
  990. if (usefieldalignment=bit_alignment) then
  991. databitsize:=offset*8;
  992. { We move the ownership of the defs and symbols to the new recordsymtable.
  993. The old unionsymtable keeps the references, but doesn't own the
  994. objects anymore }
  995. unionst.DefList.OwnsObjects:=false;
  996. unionst.SymList.OwnsObjects:=false;
  997. { copy symbols }
  998. for i:=0 to unionst.SymList.Count-1 do
  999. begin
  1000. sym:=TSym(unionst.SymList[i]);
  1001. if sym.typ<>fieldvarsym then
  1002. internalerror(200601272);
  1003. if tfieldvarsym(sym).fieldoffset=0 then
  1004. include(tfieldvarsym(sym).varoptions,vo_is_first_field);
  1005. { add to this record symtable }
  1006. // unionst.SymList.List.List^[i].Data:=nil;
  1007. sym.ChangeOwner(self);
  1008. varalign:=tfieldvarsym(sym).vardef.alignment;
  1009. if varalign=0 then
  1010. varalign:=size_2_align(tfieldvarsym(sym).getsize);
  1011. { retrieve size }
  1012. if (usefieldalignment=bit_alignment) then
  1013. begin
  1014. { bit packed records are limited to high(aint) bits }
  1015. { instead of bytes to avoid double precision }
  1016. { arithmetic in offset calculations }
  1017. if is_ordinal(tfieldvarsym(sym).vardef) then
  1018. bitsize:=tfieldvarsym(sym).getpackedbitsize
  1019. else
  1020. begin
  1021. bitsize:=tfieldvarsym(sym).getsize;
  1022. if (bitsize>high(aint) div 8) then
  1023. Message(sym_e_segment_too_large);
  1024. bitsize:=bitsize*8;
  1025. end;
  1026. if bitsize>high(aint)-databitsize then
  1027. begin
  1028. Message(sym_e_segment_too_large);
  1029. _datasize:=high(aint);
  1030. databitsize:=high(aint);
  1031. end
  1032. else
  1033. begin
  1034. databitsize:=tfieldvarsym(sym).fieldoffset+offset*8;
  1035. _datasize:=(databitsize+7) div 8;
  1036. end;
  1037. tfieldvarsym(sym).fieldoffset:=databitsize;
  1038. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset div 8,varalign);
  1039. end
  1040. else
  1041. begin
  1042. if tfieldvarsym(sym).getsize>high(aint)-_datasize then
  1043. begin
  1044. Message(sym_e_segment_too_large);
  1045. _datasize:=high(aint);
  1046. end
  1047. else
  1048. _datasize:=tfieldvarsym(sym).fieldoffset+offset;
  1049. { update address }
  1050. tfieldvarsym(sym).fieldoffset:=_datasize;
  1051. varalignrecord:=field2recordalignment(tfieldvarsym(sym).fieldoffset,varalign);
  1052. end;
  1053. { update alignment of this record }
  1054. if (usefieldalignment<>C_alignment) and
  1055. (usefieldalignment<>mac68k_alignment) then
  1056. recordalignment:=max(recordalignment,varalignrecord);
  1057. end;
  1058. { update alignment for C records }
  1059. if (usefieldalignment=C_alignment) and
  1060. (usefieldalignment<>mac68k_alignment) then
  1061. recordalignment:=max(recordalignment,unionst.recordalignment);
  1062. { Register defs in the new record symtable }
  1063. for i:=0 to unionst.DefList.Count-1 do
  1064. begin
  1065. def:=TDef(unionst.DefList[i]);
  1066. def.ChangeOwner(self);
  1067. end;
  1068. _datasize:=storesize;
  1069. fieldalignment:=storealign;
  1070. { If a record contains a union, it does not contain a "single
  1071. non-composite field" in the context of certain ABIs requiring
  1072. special treatment for such records }
  1073. if defowner.typ=recorddef then
  1074. trecorddef(defowner).isunion:=true;
  1075. end;
  1076. {****************************************************************************
  1077. TObjectSymtable
  1078. ****************************************************************************}
  1079. constructor tObjectSymtable.create(adefowner:tdef;const n:string;usealign:shortint);
  1080. begin
  1081. inherited create(n,usealign);
  1082. symtabletype:=ObjectSymtable;
  1083. defowner:=adefowner;
  1084. end;
  1085. function tObjectSymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1086. var
  1087. hsym : tsym;
  1088. begin
  1089. result:=false;
  1090. if not assigned(defowner) then
  1091. internalerror(200602061);
  1092. { procsym and propertysym have special code
  1093. to override values in inherited classes. For other
  1094. symbols check for duplicates }
  1095. if not(sym.typ in [procsym,propertysym]) then
  1096. begin
  1097. { but private ids can be reused }
  1098. hsym:=search_struct_member(tobjectdef(defowner),hashedid.id);
  1099. if assigned(hsym) and
  1100. (
  1101. (
  1102. not(m_delphi in current_settings.modeswitches) and
  1103. is_visible_for_object(hsym,tobjectdef(defowner))
  1104. ) or
  1105. (
  1106. { In Delphi, you can repeat members of a parent class. You can't }
  1107. { do this for objects however, and you (obviouly) can't }
  1108. { declare two fields with the same name in a single class }
  1109. (m_delphi in current_settings.modeswitches) and
  1110. (
  1111. is_object(tdef(defowner)) or
  1112. (hsym.owner = self)
  1113. )
  1114. )
  1115. ) then
  1116. begin
  1117. DuplicateSym(hashedid,sym,hsym);
  1118. result:=true;
  1119. end;
  1120. end
  1121. else
  1122. begin
  1123. if not(m_duplicate_names in current_settings.modeswitches) then
  1124. result:=inherited checkduplicate(hashedid,sym);
  1125. end;
  1126. end;
  1127. {****************************************************************************
  1128. TAbstractLocalSymtable
  1129. ****************************************************************************}
  1130. procedure tabstractlocalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1131. var
  1132. oldtyp : byte;
  1133. begin
  1134. oldtyp:=ppufile.entrytyp;
  1135. ppufile.entrytyp:=subentryid;
  1136. inherited ppuwrite(ppufile);
  1137. ppufile.entrytyp:=oldtyp;
  1138. end;
  1139. function tabstractlocalsymtable.count_locals:longint;
  1140. var
  1141. i : longint;
  1142. sym : tsym;
  1143. begin
  1144. result:=0;
  1145. for i:=0 to SymList.Count-1 do
  1146. begin
  1147. sym:=tsym(SymList[i]);
  1148. { Count only varsyms, but ignore the funcretsym }
  1149. if (tsym(sym).typ in [localvarsym,paravarsym]) and
  1150. (tsym(sym)<>current_procinfo.procdef.funcretsym) and
  1151. (not(vo_is_parentfp in tabstractvarsym(sym).varoptions) or
  1152. (tstoredsym(sym).refs>0)) then
  1153. inc(result);
  1154. end;
  1155. end;
  1156. {****************************************************************************
  1157. TLocalSymtable
  1158. ****************************************************************************}
  1159. constructor tlocalsymtable.create(adefowner:tdef;level:byte);
  1160. begin
  1161. inherited create('');
  1162. defowner:=adefowner;
  1163. symtabletype:=localsymtable;
  1164. symtablelevel:=level;
  1165. end;
  1166. function tlocalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1167. var
  1168. hsym : tsym;
  1169. begin
  1170. if not assigned(defowner) or
  1171. (defowner.typ<>procdef) then
  1172. internalerror(200602042);
  1173. result:=false;
  1174. hsym:=tsym(FindWithHash(hashedid));
  1175. if assigned(hsym) then
  1176. begin
  1177. { a local and the function can have the same
  1178. name in TP and Delphi, but RESULT not }
  1179. if (m_duplicate_names in current_settings.modeswitches) and
  1180. (hsym.typ in [absolutevarsym,localvarsym]) and
  1181. (vo_is_funcret in tabstractvarsym(hsym).varoptions) and
  1182. not((m_result in current_settings.modeswitches) and
  1183. (vo_is_result in tabstractvarsym(hsym).varoptions)) then
  1184. HideSym(hsym)
  1185. else
  1186. DuplicateSym(hashedid,sym,hsym);
  1187. result:=true;
  1188. exit;
  1189. end;
  1190. { check also parasymtable, this needs to be done here because
  1191. of the special situation with the funcret sym that needs to be
  1192. hidden for tp and delphi modes }
  1193. hsym:=tsym(tabstractprocdef(defowner).parast.FindWithHash(hashedid));
  1194. if assigned(hsym) then
  1195. begin
  1196. { a local and the function can have the same
  1197. name in TP and Delphi, but RESULT not }
  1198. if (m_duplicate_names in current_settings.modeswitches) and
  1199. (sym.typ in [absolutevarsym,localvarsym]) and
  1200. (vo_is_funcret in tabstractvarsym(sym).varoptions) and
  1201. not((m_result in current_settings.modeswitches) and
  1202. (vo_is_result in tabstractvarsym(sym).varoptions)) then
  1203. Hidesym(sym)
  1204. else
  1205. DuplicateSym(hashedid,sym,hsym);
  1206. result:=true;
  1207. exit;
  1208. end;
  1209. { check ObjectSymtable, skip this for funcret sym because
  1210. that will always be positive because it has the same name
  1211. as the procsym }
  1212. if not is_funcret_sym(sym) and
  1213. (defowner.typ=procdef) and
  1214. assigned(tprocdef(defowner).struct) and
  1215. (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
  1216. (
  1217. not(m_delphi in current_settings.modeswitches) or
  1218. is_object(tprocdef(defowner).struct)
  1219. ) then
  1220. result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
  1221. end;
  1222. {****************************************************************************
  1223. TParaSymtable
  1224. ****************************************************************************}
  1225. constructor tparasymtable.create(adefowner:tdef;level:byte);
  1226. begin
  1227. inherited create('');
  1228. readonly:=false;
  1229. defowner:=adefowner;
  1230. symtabletype:=parasymtable;
  1231. symtablelevel:=level;
  1232. end;
  1233. function tparasymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1234. begin
  1235. result:=inherited checkduplicate(hashedid,sym);
  1236. if result then
  1237. exit;
  1238. if not(m_duplicate_names in current_settings.modeswitches) and
  1239. (defowner.typ=procdef) and
  1240. assigned(tprocdef(defowner).struct) and
  1241. (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
  1242. (
  1243. not(m_delphi in current_settings.modeswitches) or
  1244. is_object(tprocdef(defowner).struct)
  1245. ) then
  1246. result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
  1247. end;
  1248. procedure tparasymtable.insertdef(def: TDefEntry);
  1249. begin
  1250. if readonly then
  1251. defowner.owner.insertdef(def)
  1252. else
  1253. inherited insertdef(def);
  1254. end;
  1255. {****************************************************************************
  1256. TAbstractUniTSymtable
  1257. ****************************************************************************}
  1258. constructor tabstractuniTSymtable.create(const n : string;id:word);
  1259. begin
  1260. inherited create(n);
  1261. moduleid:=id;
  1262. end;
  1263. function tabstractuniTSymtable.iscurrentunit:boolean;
  1264. begin
  1265. result:=assigned(current_module) and
  1266. (
  1267. (current_module.globalsymtable=self) or
  1268. (current_module.localsymtable=self)
  1269. );
  1270. end;
  1271. {****************************************************************************
  1272. TStaticSymtable
  1273. ****************************************************************************}
  1274. constructor tstaticsymtable.create(const n : string;id:word);
  1275. begin
  1276. inherited create(n,id);
  1277. symtabletype:=staticsymtable;
  1278. symtablelevel:=main_program_level;
  1279. end;
  1280. procedure tstaticsymtable.ppuload(ppufile:tcompilerppufile);
  1281. begin
  1282. inherited ppuload(ppufile);
  1283. { now we can deref the syms and defs }
  1284. deref;
  1285. end;
  1286. procedure tstaticsymtable.ppuwrite(ppufile:tcompilerppufile);
  1287. begin
  1288. inherited ppuwrite(ppufile);
  1289. end;
  1290. function tstaticsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1291. var
  1292. hsym : tsym;
  1293. begin
  1294. result:=false;
  1295. hsym:=tsym(FindWithHash(hashedid));
  1296. if assigned(hsym) then
  1297. begin
  1298. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1299. unit, the unit can then not be accessed anymore using
  1300. <unit>.<id>, so we can hide the symbol }
  1301. if (m_delphi in current_settings.modeswitches) and
  1302. (hsym.typ=symconst.unitsym) then
  1303. HideSym(hsym)
  1304. else
  1305. DuplicateSym(hashedid,sym,hsym);
  1306. result:=true;
  1307. exit;
  1308. end;
  1309. if (current_module.localsymtable=self) and
  1310. assigned(current_module.globalsymtable) then
  1311. result:=tglobalsymtable(current_module.globalsymtable).checkduplicate(hashedid,sym);
  1312. end;
  1313. {****************************************************************************
  1314. TGlobalSymtable
  1315. ****************************************************************************}
  1316. constructor tglobalsymtable.create(const n : string;id:word);
  1317. begin
  1318. inherited create(n,id);
  1319. symtabletype:=globalsymtable;
  1320. symtablelevel:=main_program_level;
  1321. end;
  1322. procedure tglobalsymtable.ppuload(ppufile:tcompilerppufile);
  1323. begin
  1324. inherited ppuload(ppufile);
  1325. { now we can deref the syms and defs }
  1326. deref;
  1327. end;
  1328. procedure tglobalsymtable.ppuwrite(ppufile:tcompilerppufile);
  1329. begin
  1330. { write the symtable entries }
  1331. inherited ppuwrite(ppufile);
  1332. end;
  1333. function tglobalsymtable.checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;
  1334. var
  1335. hsym : tsym;
  1336. begin
  1337. result:=false;
  1338. hsym:=tsym(FindWithHash(hashedid));
  1339. if assigned(hsym) then
  1340. begin
  1341. { Delphi (contrary to TP) you can have a symbol with the same name as the
  1342. unit, the unit can then not be accessed anymore using
  1343. <unit>.<id>, so we can hide the symbol }
  1344. if (m_delphi in current_settings.modeswitches) and
  1345. (hsym.typ=symconst.unitsym) then
  1346. HideSym(hsym)
  1347. else
  1348. DuplicateSym(hashedid,sym,hsym);
  1349. result:=true;
  1350. exit;
  1351. end;
  1352. end;
  1353. {****************************************************************************
  1354. TWITHSYMTABLE
  1355. ****************************************************************************}
  1356. constructor twithsymtable.create(aowner:tdef;ASymList:TFPHashObjectList;refnode:tobject{tnode});
  1357. begin
  1358. inherited create('');
  1359. symtabletype:=withsymtable;
  1360. withrefnode:=refnode;
  1361. { Replace SymList with the passed symlist }
  1362. SymList.free;
  1363. SymList:=ASymList;
  1364. defowner:=aowner;
  1365. end;
  1366. destructor twithsymtable.destroy;
  1367. begin
  1368. withrefnode.free;
  1369. { Disable SymList because we don't Own it }
  1370. SymList:=nil;
  1371. inherited destroy;
  1372. end;
  1373. procedure twithsymtable.clear;
  1374. begin
  1375. { remove no entry from a withsymtable as it is only a pointer to the
  1376. recorddef or objectdef symtable }
  1377. end;
  1378. procedure twithsymtable.insertdef(def:TDefEntry);
  1379. begin
  1380. { Definitions can't be registered in the withsymtable
  1381. because the withsymtable is removed after the with block.
  1382. We can't easily solve it here because the next symtable in the
  1383. stack is not known. }
  1384. internalerror(200602046);
  1385. end;
  1386. {****************************************************************************
  1387. TSTT_ExceptionSymtable
  1388. ****************************************************************************}
  1389. constructor tstt_excepTSymtable.create;
  1390. begin
  1391. inherited create('');
  1392. symtabletype:=stt_excepTSymtable;
  1393. end;
  1394. {****************************************************************************
  1395. TMacroSymtable
  1396. ****************************************************************************}
  1397. constructor tmacrosymtable.create(exported: boolean);
  1398. begin
  1399. inherited create('');
  1400. if exported then
  1401. symtabletype:=exportedmacrosymtable
  1402. else
  1403. symtabletype:=localmacrosymtable;
  1404. symtablelevel:=main_program_level;
  1405. end;
  1406. {****************************************************************************
  1407. TEnumSymtable
  1408. ****************************************************************************}
  1409. procedure tenumsymtable.insert(sym: TSymEntry; checkdup: boolean);
  1410. var
  1411. value: longint;
  1412. def: tenumdef;
  1413. begin
  1414. // defowner = nil only when we are loading from ppu
  1415. if defowner<>nil then
  1416. begin
  1417. { First entry? Then we need to set the minval }
  1418. value:=tenumsym(sym).value;
  1419. def:=tenumdef(defowner);
  1420. if SymList.count=0 then
  1421. begin
  1422. if value>0 then
  1423. def.has_jumps:=true;
  1424. def.setmin(value);
  1425. def.setmax(value);
  1426. end
  1427. else
  1428. begin
  1429. { check for jumps }
  1430. if value>def.max+1 then
  1431. def.has_jumps:=true;
  1432. { update low and high }
  1433. if def.min>value then
  1434. def.setmin(value);
  1435. if def.max<value then
  1436. def.setmax(value);
  1437. end;
  1438. end;
  1439. inherited insert(sym, checkdup);
  1440. end;
  1441. constructor tenumsymtable.create(adefowner: tdef);
  1442. begin
  1443. inherited Create('');
  1444. symtabletype:=enumsymtable;
  1445. defowner:=adefowner;
  1446. end;
  1447. {****************************************************************************
  1448. TArraySymtable
  1449. ****************************************************************************}
  1450. procedure tarraysymtable.insertdef(def: TDefEntry);
  1451. begin
  1452. { Enums must also be available outside the record scope,
  1453. insert in the owner of this symtable }
  1454. if def.typ=enumdef then
  1455. defowner.owner.insertdef(def)
  1456. else
  1457. inherited insertdef(def);
  1458. end;
  1459. constructor tarraysymtable.create(adefowner: tdef);
  1460. begin
  1461. inherited Create('');
  1462. symtabletype:=arraysymtable;
  1463. defowner:=adefowner;
  1464. end;
  1465. {*****************************************************************************
  1466. Helper Routines
  1467. *****************************************************************************}
  1468. function FullTypeName(def,otherdef:tdef):string;
  1469. var
  1470. s1,s2 : string;
  1471. begin
  1472. if def.typ in [objectdef,recorddef] then
  1473. s1:=tabstractrecorddef(def).RttiName
  1474. else
  1475. s1:=def.typename;
  1476. { When the names are the same try to include the unit name }
  1477. if assigned(otherdef) and
  1478. (def.owner.symtabletype in [globalsymtable,staticsymtable]) then
  1479. begin
  1480. s2:=otherdef.typename;
  1481. if upper(s1)=upper(s2) then
  1482. s1:=def.owner.realname^+'.'+s1;
  1483. end;
  1484. FullTypeName:=s1;
  1485. end;
  1486. function generate_nested_name(symtable:tsymtable;delimiter:string):string;
  1487. begin
  1488. result:='';
  1489. while assigned(symtable) and (symtable.symtabletype in [ObjectSymtable,recordsymtable]) do
  1490. begin
  1491. if (result='') then
  1492. result:=symtable.name^
  1493. else
  1494. result:=symtable.name^+delimiter+result;
  1495. symtable:=symtable.defowner.owner;
  1496. end;
  1497. end;
  1498. procedure incompatibletypes(def1,def2:tdef);
  1499. begin
  1500. { When there is an errordef there is already an error message show }
  1501. if (def2.typ=errordef) or
  1502. (def1.typ=errordef) then
  1503. exit;
  1504. CGMessage2(type_e_incompatible_types,FullTypeName(def1,def2),FullTypeName(def2,def1));
  1505. end;
  1506. procedure hidesym(sym:TSymEntry);
  1507. begin
  1508. sym.realname:='$hidden'+sym.realname;
  1509. tsym(sym).visibility:=vis_hidden;
  1510. end;
  1511. procedure duplicatesym(var hashedid:THashedIDString;dupsym,origsym:TSymEntry);
  1512. var
  1513. st : TSymtable;
  1514. begin
  1515. Message1(sym_e_duplicate_id,tsym(origsym).realname);
  1516. { Write hint where the original symbol was found }
  1517. st:=finduniTSymtable(origsym.owner);
  1518. with tsym(origsym).fileinfo do
  1519. begin
  1520. if assigned(st) and
  1521. (st.symtabletype=globalsymtable) and
  1522. st.iscurrentunit then
  1523. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line))
  1524. else if assigned(st.name) then
  1525. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line));
  1526. end;
  1527. { Rename duplicate sym to an unreachable name, but it can be
  1528. inserted in the symtable without errors }
  1529. inc(dupnr);
  1530. hashedid.id:='dup'+tostr(dupnr)+hashedid.id;
  1531. if assigned(dupsym) then
  1532. include(tsym(dupsym).symoptions,sp_implicitrename);
  1533. end;
  1534. {*****************************************************************************
  1535. Search
  1536. *****************************************************************************}
  1537. procedure addsymref(sym:tsym);
  1538. begin
  1539. { symbol uses count }
  1540. sym.IncRefCount;
  1541. { unit uses count }
  1542. if assigned(current_module) and
  1543. (sym.owner.symtabletype=globalsymtable) then
  1544. begin
  1545. if tglobalsymtable(sym.owner).moduleid>=current_module.unitmapsize then
  1546. internalerror(200501152);
  1547. inc(current_module.unitmap[tglobalsymtable(sym.owner).moduleid].refs);
  1548. end;
  1549. end;
  1550. function is_owned_by(childdef,ownerdef:tabstractrecorddef):boolean;
  1551. begin
  1552. result:=childdef=ownerdef;
  1553. if not result and (childdef.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  1554. result:=is_owned_by(tabstractrecorddef(childdef.owner.defowner),ownerdef);
  1555. end;
  1556. function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tabstractrecorddef):boolean;
  1557. var
  1558. symownerdef : tabstractrecorddef;
  1559. begin
  1560. result:=false;
  1561. { Get objdectdef owner of the symtable for the is_related checks }
  1562. if not assigned(symst) or
  1563. not (symst.symtabletype in [objectsymtable,recordsymtable]) then
  1564. internalerror(200810285);
  1565. symownerdef:=tabstractrecorddef(symst.defowner);
  1566. case symvisibility of
  1567. vis_private :
  1568. begin
  1569. { private symbols are allowed when we are in the same
  1570. module as they are defined }
  1571. result:=(
  1572. (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1573. (symownerdef.owner.iscurrentunit)
  1574. ) or
  1575. ( // the case of specialize inside the generic declaration
  1576. (symownerdef.owner.symtabletype = objectsymtable) and
  1577. (
  1578. assigned(current_structdef) and
  1579. (
  1580. (current_structdef=symownerdef) or
  1581. (current_structdef.owner.iscurrentunit)
  1582. )
  1583. ) or
  1584. (
  1585. not assigned(current_structdef) and
  1586. (symownerdef.owner.iscurrentunit)
  1587. )
  1588. );
  1589. end;
  1590. vis_strictprivate :
  1591. begin
  1592. result:=assigned(current_structdef) and
  1593. is_owned_by(current_structdef,symownerdef);
  1594. end;
  1595. vis_strictprotected :
  1596. begin
  1597. result:=assigned(current_structdef) and
  1598. (current_structdef.is_related(symownerdef) or
  1599. is_owned_by(current_structdef,symownerdef));
  1600. end;
  1601. vis_protected :
  1602. begin
  1603. { protected symbols are visible in the module that defines them and
  1604. also visible to related objects. The related object must be defined
  1605. in the current module }
  1606. result:=(
  1607. (
  1608. (symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1609. (symownerdef.owner.iscurrentunit)
  1610. ) or
  1611. (
  1612. assigned(contextobjdef) and
  1613. (contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable,ObjectSymtable]) and
  1614. (contextobjdef.owner.iscurrentunit) and
  1615. contextobjdef.is_related(symownerdef)
  1616. ) or
  1617. ( // the case of specialize inside the generic declaration
  1618. (symownerdef.owner.symtabletype = objectsymtable) and
  1619. (
  1620. assigned(current_structdef) and
  1621. (
  1622. (current_structdef=symownerdef) or
  1623. (current_structdef.owner.iscurrentunit)
  1624. )
  1625. ) or
  1626. (
  1627. not assigned(current_structdef) and
  1628. (symownerdef.owner.iscurrentunit)
  1629. )
  1630. )
  1631. );
  1632. end;
  1633. vis_public,
  1634. vis_published :
  1635. result:=true;
  1636. end;
  1637. end;
  1638. function is_visible_for_object(pd:tprocdef;contextobjdef:tabstractrecorddef):boolean;
  1639. begin
  1640. result:=is_visible_for_object(pd.owner,pd.visibility,contextobjdef);
  1641. end;
  1642. function is_visible_for_object(sym:tsym;contextobjdef:tabstractrecorddef):boolean;
  1643. var
  1644. i : longint;
  1645. pd : tprocdef;
  1646. begin
  1647. if sym.typ=procsym then
  1648. begin
  1649. { A procsym is visible, when there is at least one of the procdefs visible }
  1650. result:=false;
  1651. for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
  1652. begin
  1653. pd:=tprocdef(tprocsym(sym).ProcdefList[i]);
  1654. if (pd.owner=sym.owner) and
  1655. is_visible_for_object(pd,contextobjdef) then
  1656. begin
  1657. result:=true;
  1658. exit;
  1659. end;
  1660. end;
  1661. end
  1662. else
  1663. result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
  1664. end;
  1665. function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1666. var
  1667. hashedid : THashedIDString;
  1668. contextstructdef : tabstractrecorddef;
  1669. stackitem : psymtablestackitem;
  1670. begin
  1671. result:=false;
  1672. hashedid.id:=s;
  1673. stackitem:=symtablestack.stack;
  1674. while assigned(stackitem) do
  1675. begin
  1676. srsymtable:=stackitem^.symtable;
  1677. if (srsymtable.symtabletype=objectsymtable) then
  1678. begin
  1679. if searchsym_in_class(tobjectdef(srsymtable.defowner),tobjectdef(srsymtable.defowner),s,srsym,srsymtable) then
  1680. begin
  1681. result:=true;
  1682. exit;
  1683. end;
  1684. end
  1685. else
  1686. begin
  1687. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1688. if assigned(srsym) then
  1689. begin
  1690. { use the class from withsymtable only when it is
  1691. defined in this unit }
  1692. if (srsymtable.symtabletype=withsymtable) and
  1693. assigned(srsymtable.defowner) and
  1694. (srsymtable.defowner.typ in [recorddef,objectdef]) and
  1695. (srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1696. (srsymtable.defowner.owner.iscurrentunit) then
  1697. contextstructdef:=tobjectdef(srsymtable.defowner)
  1698. else
  1699. contextstructdef:=current_structdef;
  1700. if not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
  1701. is_visible_for_object(srsym,contextstructdef) then
  1702. begin
  1703. { we need to know if a procedure references symbols
  1704. in the static symtable, because then it can't be
  1705. inlined from outside this unit }
  1706. if assigned(current_procinfo) and
  1707. (srsym.owner.symtabletype=staticsymtable) then
  1708. include(current_procinfo.flags,pi_uses_static_symtable);
  1709. addsymref(srsym);
  1710. result:=true;
  1711. exit;
  1712. end;
  1713. end;
  1714. end;
  1715. stackitem:=stackitem^.next;
  1716. end;
  1717. srsym:=nil;
  1718. srsymtable:=nil;
  1719. end;
  1720. function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1721. var
  1722. hashedid : THashedIDString;
  1723. stackitem : psymtablestackitem;
  1724. classh : tobjectdef;
  1725. begin
  1726. result:=false;
  1727. hashedid.id:=s;
  1728. stackitem:=symtablestack.stack;
  1729. while assigned(stackitem) do
  1730. begin
  1731. {
  1732. It is not possible to have type symbols in:
  1733. parameters
  1734. Exception are classes, objects, records, generic definitions and specializations
  1735. that have the parameterized types inserted in the symtable.
  1736. }
  1737. srsymtable:=stackitem^.symtable;
  1738. if (srsymtable.symtabletype=ObjectSymtable) then
  1739. begin
  1740. classh:=tobjectdef(srsymtable.defowner);
  1741. while assigned(classh) do
  1742. begin
  1743. srsymtable:=classh.symtable;
  1744. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1745. if assigned(srsym) and
  1746. not(srsym.typ in [fieldvarsym,paravarsym,propertysym,procsym,labelsym]) and
  1747. is_visible_for_object(srsym,current_structdef) then
  1748. begin
  1749. addsymref(srsym);
  1750. result:=true;
  1751. exit;
  1752. end;
  1753. classh:=classh.childof;
  1754. end;
  1755. end
  1756. else
  1757. begin
  1758. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1759. if assigned(srsym) and
  1760. not(srsym.typ in [fieldvarsym,paravarsym,propertysym,procsym,labelsym]) and
  1761. (not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or is_visible_for_object(srsym,current_structdef)) then
  1762. begin
  1763. { we need to know if a procedure references symbols
  1764. in the static symtable, because then it can't be
  1765. inlined from outside this unit }
  1766. if assigned(current_procinfo) and
  1767. (srsym.owner.symtabletype=staticsymtable) then
  1768. include(current_procinfo.flags,pi_uses_static_symtable);
  1769. addsymref(srsym);
  1770. result:=true;
  1771. exit;
  1772. end;
  1773. end;
  1774. stackitem:=stackitem^.next;
  1775. end;
  1776. result:=false;
  1777. srsym:=nil;
  1778. srsymtable:=nil;
  1779. end;
  1780. function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1781. var
  1782. pmod : tmodule;
  1783. begin
  1784. pmod:=tmodule(pm);
  1785. result:=false;
  1786. if assigned(pmod.globalsymtable) then
  1787. begin
  1788. srsym:=tsym(pmod.globalsymtable.Find(s));
  1789. if assigned(srsym) then
  1790. begin
  1791. srsymtable:=pmod.globalsymtable;
  1792. addsymref(srsym);
  1793. result:=true;
  1794. exit;
  1795. end;
  1796. end;
  1797. { If the module is the current unit we also need
  1798. to search the local symtable }
  1799. if (pmod=current_module) and
  1800. assigned(pmod.localsymtable) then
  1801. begin
  1802. srsym:=tsym(pmod.localsymtable.Find(s));
  1803. if assigned(srsym) then
  1804. begin
  1805. srsymtable:=pmod.localsymtable;
  1806. addsymref(srsym);
  1807. result:=true;
  1808. exit;
  1809. end;
  1810. end;
  1811. srsym:=nil;
  1812. srsymtable:=nil;
  1813. end;
  1814. function searchsym_in_named_module(const unitname, symname: TIDString; out srsym: tsym; out srsymtable: tsymtable): boolean;
  1815. var
  1816. stackitem : psymtablestackitem;
  1817. begin
  1818. result:=false;
  1819. stackitem:=symtablestack.stack;
  1820. while assigned(stackitem) do
  1821. begin
  1822. srsymtable:=stackitem^.symtable;
  1823. if (srsymtable.symtabletype=globalsymtable) and
  1824. (srsymtable.name^=unitname) then
  1825. begin
  1826. srsym:=tsym(srsymtable.find(symname));
  1827. if not assigned(srsym) then
  1828. break;
  1829. result:=true;
  1830. exit;
  1831. end;
  1832. stackitem:=stackitem^.next;
  1833. end;
  1834. { If the module is the current unit we also need
  1835. to search the local symtable }
  1836. if (current_module.globalsymtable=srsymtable) and
  1837. assigned(current_module.localsymtable) then
  1838. begin
  1839. srsymtable:=current_module.localsymtable;
  1840. srsym:=tsym(srsymtable.find(symname));
  1841. if assigned(srsym) then
  1842. begin
  1843. result:=true;
  1844. exit;
  1845. end;
  1846. end;
  1847. end;
  1848. function find_real_objcclass_definition(pd: tobjectdef; erroronfailure: boolean): tobjectdef;
  1849. var
  1850. hashedid : THashedIDString;
  1851. stackitem : psymtablestackitem;
  1852. srsymtable : tsymtable;
  1853. srsym : tsym;
  1854. begin
  1855. { not a formal definition -> return it }
  1856. if not(oo_is_formal in pd.objectoptions) then
  1857. begin
  1858. result:=pd;
  1859. exit;
  1860. end;
  1861. hashedid.id:=pd.typesym.name;
  1862. stackitem:=symtablestack.stack;
  1863. while assigned(stackitem) do
  1864. begin
  1865. srsymtable:=stackitem^.symtable;
  1866. { ObjC classes can't appear in generics or as nested class
  1867. definitions }
  1868. if not(srsymtable.symtabletype in [recordsymtable,ObjectSymtable,parasymtable]) then
  1869. begin
  1870. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1871. if assigned(srsym) and
  1872. (srsym.typ=typesym) and
  1873. is_objcclass(ttypesym(srsym).typedef) and
  1874. not(oo_is_formal in tobjectdef(ttypesym(srsym).typedef).objectoptions) then
  1875. begin
  1876. { the external name for the formal and the real definition must match }
  1877. if tobjectdef(ttypesym(srsym).typedef).objextname^<>pd.objextname^ then
  1878. begin
  1879. Message2(sym_e_external_class_name_mismatch1,pd.objextname^,pd.typename);
  1880. MessagePos1(srsym.fileinfo,sym_e_external_class_name_mismatch2,tobjectdef(ttypesym(srsym).typedef).objextname^);
  1881. end;
  1882. result:=tobjectdef(ttypesym(srsym).typedef);
  1883. if assigned(current_procinfo) and
  1884. (srsym.owner.symtabletype=staticsymtable) then
  1885. include(current_procinfo.flags,pi_uses_static_symtable);
  1886. addsymref(srsym);
  1887. exit;
  1888. end;
  1889. end;
  1890. stackitem:=stackitem^.next;
  1891. end;
  1892. { nothing found: optionally give an error and return the original
  1893. (empty) one }
  1894. if erroronfailure then
  1895. Message1(sym_e_objc_formal_class_not_resolved,pd.objrealname^);
  1896. result:=pd;
  1897. end;
  1898. function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1899. var
  1900. hashedid : THashedIDString;
  1901. orgclass : tobjectdef;
  1902. i : longint;
  1903. begin
  1904. { search for a class helper method first if this is an Object Pascal
  1905. class }
  1906. if is_class(classh) then
  1907. begin
  1908. result:=search_objectpascal_class_helper(classh,contextclassh,s,srsym,srsymtable);
  1909. if result then
  1910. exit;
  1911. end;
  1912. orgclass:=classh;
  1913. { in case this is a formal objcclass, first find the real definition }
  1914. if assigned(classh) then
  1915. begin
  1916. if (oo_is_formal in classh.objectoptions) then
  1917. classh:=find_real_objcclass_definition(classh,true);
  1918. { The contextclassh is used for visibility. The classh must be equal to
  1919. or be a parent of contextclassh. E.g. for inherited searches the classh is the
  1920. parent. }
  1921. if not contextclassh.is_related(classh) then
  1922. internalerror(200811161);
  1923. end;
  1924. result:=false;
  1925. hashedid.id:=s;
  1926. { an Objective-C protocol can inherit from multiple other protocols
  1927. -> uses ImplementedInterfaces instead }
  1928. if is_objcprotocol(classh) then
  1929. begin
  1930. srsymtable:=classh.symtable;
  1931. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1932. if assigned(srsym) and
  1933. is_visible_for_object(srsym,contextclassh) then
  1934. begin
  1935. addsymref(srsym);
  1936. result:=true;
  1937. exit;
  1938. end;
  1939. for i:=0 to classh.ImplementedInterfaces.count-1 do
  1940. begin
  1941. if searchsym_in_class(TImplementedInterface(classh.ImplementedInterfaces[i]).intfdef,contextclassh,s,srsym,srsymtable) then
  1942. begin
  1943. result:=true;
  1944. exit;
  1945. end;
  1946. end;
  1947. end
  1948. else
  1949. begin
  1950. while assigned(classh) do
  1951. begin
  1952. srsymtable:=classh.symtable;
  1953. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1954. if assigned(srsym) and
  1955. is_visible_for_object(srsym,contextclassh) then
  1956. begin
  1957. addsymref(srsym);
  1958. result:=true;
  1959. exit;
  1960. end;
  1961. classh:=classh.childof;
  1962. end;
  1963. end;
  1964. if is_objcclass(orgclass) then
  1965. result:=search_class_helper(orgclass,s,srsym,srsymtable)
  1966. else
  1967. begin
  1968. srsym:=nil;
  1969. srsymtable:=nil;
  1970. end;
  1971. end;
  1972. function searchsym_in_record(recordh:tabstractrecorddef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1973. var
  1974. hashedid : THashedIDString;
  1975. begin
  1976. hashedid.id:=s;
  1977. srsymtable:=recordh.symtable;
  1978. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  1979. if assigned(srsym) and is_visible_for_object(srsym,recordh) then
  1980. begin
  1981. addsymref(srsym);
  1982. result:=true;
  1983. exit;
  1984. end;
  1985. srsym:=nil;
  1986. srsymtable:=nil;
  1987. end;
  1988. function searchsym_in_class_by_msgint(classh:tobjectdef;msgid:longint;out srdef : tdef;out srsym:tsym;out srsymtable:TSymtable):boolean;
  1989. var
  1990. def : tdef;
  1991. i : longint;
  1992. begin
  1993. { in case this is a formal objcclass, first find the real definition }
  1994. if assigned(classh) and
  1995. (oo_is_formal in classh.objectoptions) then
  1996. classh:=find_real_objcclass_definition(classh,true);
  1997. result:=false;
  1998. def:=nil;
  1999. while assigned(classh) do
  2000. begin
  2001. for i:=0 to classh.symtable.DefList.Count-1 do
  2002. begin
  2003. def:=tstoreddef(classh.symtable.DefList[i]);
  2004. { Find also all hidden private methods to
  2005. be compatible with delphi, see tw6203 (PFV) }
  2006. if (def.typ=procdef) and
  2007. (po_msgint in tprocdef(def).procoptions) and
  2008. (tprocdef(def).messageinf.i=msgid) then
  2009. begin
  2010. srdef:=def;
  2011. srsym:=tprocdef(def).procsym;
  2012. srsymtable:=classh.symtable;
  2013. addsymref(srsym);
  2014. result:=true;
  2015. exit;
  2016. end;
  2017. end;
  2018. classh:=classh.childof;
  2019. end;
  2020. srdef:=nil;
  2021. srsym:=nil;
  2022. srsymtable:=nil;
  2023. end;
  2024. function searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
  2025. var
  2026. def : tdef;
  2027. i : longint;
  2028. begin
  2029. { in case this is a formal objcclass, first find the real definition }
  2030. if assigned(classh) and
  2031. (oo_is_formal in classh.objectoptions) then
  2032. classh:=find_real_objcclass_definition(classh,true);
  2033. result:=false;
  2034. def:=nil;
  2035. while assigned(classh) do
  2036. begin
  2037. for i:=0 to classh.symtable.DefList.Count-1 do
  2038. begin
  2039. def:=tstoreddef(classh.symtable.DefList[i]);
  2040. { Find also all hidden private methods to
  2041. be compatible with delphi, see tw6203 (PFV) }
  2042. if (def.typ=procdef) and
  2043. (po_msgstr in tprocdef(def).procoptions) and
  2044. (tprocdef(def).messageinf.str^=s) then
  2045. begin
  2046. srsym:=tprocdef(def).procsym;
  2047. srsymtable:=classh.symtable;
  2048. addsymref(srsym);
  2049. result:=true;
  2050. exit;
  2051. end;
  2052. end;
  2053. classh:=classh.childof;
  2054. end;
  2055. srsym:=nil;
  2056. srsymtable:=nil;
  2057. end;
  2058. function search_specific_assignment_operator(assignment_type:ttoken;from_def,to_def:Tdef):Tprocdef;
  2059. var
  2060. sym : Tprocsym;
  2061. hashedid : THashedIDString;
  2062. curreq,
  2063. besteq : tequaltype;
  2064. currpd,
  2065. bestpd : tprocdef;
  2066. stackitem : psymtablestackitem;
  2067. begin
  2068. hashedid.id:=overloaded_names[assignment_type];
  2069. besteq:=te_incompatible;
  2070. bestpd:=nil;
  2071. stackitem:=symtablestack.stack;
  2072. while assigned(stackitem) do
  2073. begin
  2074. sym:=Tprocsym(stackitem^.symtable.FindWithHash(hashedid));
  2075. if sym<>nil then
  2076. begin
  2077. if sym.typ<>procsym then
  2078. internalerror(200402031);
  2079. { if the source type is an alias then this is only the second choice,
  2080. if you mess with this code, check tw4093 }
  2081. currpd:=sym.find_procdef_assignment_operator(from_def,to_def,curreq);
  2082. if curreq>besteq then
  2083. begin
  2084. besteq:=curreq;
  2085. bestpd:=currpd;
  2086. if (besteq=te_exact) then
  2087. break;
  2088. end;
  2089. end;
  2090. stackitem:=stackitem^.next;
  2091. end;
  2092. result:=bestpd;
  2093. end;
  2094. function search_assignment_operator(from_def,to_def:Tdef;explicit:boolean):Tprocdef;
  2095. begin
  2096. { search record/object symtable first for a suitable operator }
  2097. if from_def.typ in [recorddef,objectdef] then
  2098. symtablestack.push(tabstractrecorddef(from_def).symtable);
  2099. if to_def.typ in [recorddef,objectdef] then
  2100. symtablestack.push(tabstractrecorddef(to_def).symtable);
  2101. { if type conversion is explicit then search first for explicit
  2102. operator overload and if not found then use implicit operator }
  2103. if explicit then
  2104. result:=search_specific_assignment_operator(_OP_EXPLICIT,from_def,to_def)
  2105. else
  2106. result:=nil;
  2107. if result=nil then
  2108. result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,to_def);
  2109. { restore symtable stack }
  2110. if to_def.typ in [recorddef,objectdef] then
  2111. symtablestack.pop(tabstractrecorddef(to_def).symtable);
  2112. if from_def.typ in [recorddef,objectdef] then
  2113. symtablestack.pop(tabstractrecorddef(from_def).symtable);
  2114. end;
  2115. function search_enumerator_operator(from_def,to_def:Tdef): Tprocdef;
  2116. var
  2117. sym : Tprocsym;
  2118. hashedid : THashedIDString;
  2119. curreq,
  2120. besteq : tequaltype;
  2121. currpd,
  2122. bestpd : tprocdef;
  2123. stackitem : psymtablestackitem;
  2124. begin
  2125. hashedid.id:='enumerator';
  2126. besteq:=te_incompatible;
  2127. bestpd:=nil;
  2128. stackitem:=symtablestack.stack;
  2129. while assigned(stackitem) do
  2130. begin
  2131. sym:=Tprocsym(stackitem^.symtable.FindWithHash(hashedid));
  2132. if sym<>nil then
  2133. begin
  2134. if sym.typ<>procsym then
  2135. internalerror(200910241);
  2136. { if the source type is an alias then this is only the second choice,
  2137. if you mess with this code, check tw4093 }
  2138. currpd:=sym.find_procdef_enumerator_operator(from_def,to_def,curreq);
  2139. if curreq>besteq then
  2140. begin
  2141. besteq:=curreq;
  2142. bestpd:=currpd;
  2143. if (besteq=te_exact) then
  2144. break;
  2145. end;
  2146. end;
  2147. stackitem:=stackitem^.next;
  2148. end;
  2149. result:=bestpd;
  2150. end;
  2151. function search_system_type(const s: TIDString): ttypesym;
  2152. var
  2153. sym : tsym;
  2154. begin
  2155. sym:=tsym(systemunit.Find(s));
  2156. if not assigned(sym) or
  2157. (sym.typ<>typesym) then
  2158. cgmessage1(cg_f_unknown_system_type,s);
  2159. result:=ttypesym(sym);
  2160. end;
  2161. function search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
  2162. var
  2163. srsymtable: tsymtable;
  2164. sym: tsym;
  2165. begin
  2166. if searchsym_in_named_module(unitname,typename,sym,srsymtable) and
  2167. (sym.typ=typesym) then
  2168. begin
  2169. result:=ttypesym(sym);
  2170. exit;
  2171. end
  2172. else
  2173. begin
  2174. if throwerror then
  2175. cgmessage2(cg_f_unknown_type_in_unit,typename,unitname);
  2176. result:=nil;
  2177. end;
  2178. end;
  2179. function search_last_objectpascal_classhelper(pd : tobjectdef;out odef : tobjectdef):boolean;
  2180. var
  2181. stackitem : psymtablestackitem;
  2182. i : integer;
  2183. srsymtable : tsymtable;
  2184. begin
  2185. result:=false;
  2186. stackitem:=symtablestack.stack;
  2187. while assigned(stackitem) do
  2188. begin
  2189. srsymtable:=stackitem^.symtable;
  2190. { only check symtables that contain a class helper }
  2191. if (srsymtable.symtabletype in [staticsymtable,globalsymtable]) and
  2192. (sto_has_classhelper in srsymtable.tableoptions) then
  2193. begin
  2194. { we need to search from last to first }
  2195. for i:=srsymtable.symlist.count-1 downto 0 do
  2196. begin
  2197. if not (srsymtable.symlist[i] is ttypesym) then
  2198. continue;
  2199. if not is_objectpascal_classhelper(ttypesym(srsymtable.symlist[i]).typedef) then
  2200. continue;
  2201. odef:=tobjectdef(ttypesym(srsymtable.symlist[i]).typedef);
  2202. { does the class helper extend the correct class? }
  2203. result:=odef.childof=pd;
  2204. if result then
  2205. exit
  2206. else
  2207. odef:=nil;
  2208. end;
  2209. end;
  2210. stackitem:=stackitem^.next;
  2211. end;
  2212. end;
  2213. function search_objectpascal_class_helper(pd,contextclassh : tobjectdef;const s: string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2214. var
  2215. hashedid : THashedIDString;
  2216. classh : tobjectdef;
  2217. i : integer;
  2218. pdef : tprocdef;
  2219. begin
  2220. result:=false;
  2221. { if there is no class helper for the class then there is no need to
  2222. search further }
  2223. if not search_last_objectpascal_classhelper(pd,classh) then
  2224. exit;
  2225. hashedid.id:=s;
  2226. repeat
  2227. srsymtable:=classh.symtable;
  2228. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2229. if srsym<>nil then
  2230. begin
  2231. if srsym.typ=propertysym then
  2232. begin
  2233. result:=true;
  2234. exit;
  2235. end;
  2236. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2237. begin
  2238. pdef:=tprocdef(tprocsym(srsym).procdeflist[i]);
  2239. if not is_visible_for_object(pdef.owner,pdef.visibility,contextclassh) then
  2240. continue;
  2241. { we need to know if a procedure references symbols
  2242. in the static symtable, because then it can't be
  2243. inlined from outside this unit }
  2244. if assigned(current_procinfo) and
  2245. (srsym.owner.symtabletype=staticsymtable) then
  2246. include(current_procinfo.flags,pi_uses_static_symtable);
  2247. { no need to keep looking. There might be other
  2248. categories that extend this, a parent or child
  2249. class with a method with the same name (either
  2250. overriding this one, or overridden by this one),
  2251. but that doesn't matter as far as the basic
  2252. procsym is concerned.
  2253. }
  2254. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2255. srsymtable:=srsym.owner;
  2256. addsymref(srsym);
  2257. result:=true;
  2258. exit;
  2259. end;
  2260. end;
  2261. { try the class helper "parent" if available }
  2262. classh:=classh.helperparent;
  2263. until classh=nil;
  2264. srsym:=nil;
  2265. srsymtable:=nil;
  2266. end;
  2267. function search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2268. var
  2269. hashedid : THashedIDString;
  2270. stackitem : psymtablestackitem;
  2271. i : longint;
  2272. defowner : tobjectdef;
  2273. begin
  2274. hashedid.id:=class_helper_prefix+s;
  2275. stackitem:=symtablestack.stack;
  2276. while assigned(stackitem) do
  2277. begin
  2278. srsymtable:=stackitem^.symtable;
  2279. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2280. if assigned(srsym) then
  2281. begin
  2282. if not(srsymtable.symtabletype in [globalsymtable,staticsymtable]) or
  2283. not(srsym.owner.symtabletype in [globalsymtable,staticsymtable]) or
  2284. (srsym.typ<>procsym) then
  2285. internalerror(2009111505);
  2286. { check whether this procsym includes a helper for this particular class }
  2287. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2288. begin
  2289. { does pd inherit from (or is the same as) the class
  2290. that this method's category extended?
  2291. Warning: this list contains both category and objcclass methods
  2292. (for id.randommethod), so only check category methods here
  2293. }
  2294. defowner:=tobjectdef(tprocdef(tprocsym(srsym).procdeflist[i]).owner.defowner);
  2295. if (oo_is_classhelper in defowner.objectoptions) and
  2296. pd.is_related(defowner.childof) then
  2297. begin
  2298. { we need to know if a procedure references symbols
  2299. in the static symtable, because then it can't be
  2300. inlined from outside this unit }
  2301. if assigned(current_procinfo) and
  2302. (srsym.owner.symtabletype=staticsymtable) then
  2303. include(current_procinfo.flags,pi_uses_static_symtable);
  2304. { no need to keep looking. There might be other
  2305. categories that extend this, a parent or child
  2306. class with a method with the same name (either
  2307. overriding this one, or overridden by this one),
  2308. but that doesn't matter as far as the basic
  2309. procsym is concerned.
  2310. }
  2311. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2312. srsymtable:=srsym.owner;
  2313. addsymref(srsym);
  2314. result:=true;
  2315. exit;
  2316. end;
  2317. end;
  2318. end;
  2319. stackitem:=stackitem^.next;
  2320. end;
  2321. srsym:=nil;
  2322. srsymtable:=nil;
  2323. result:=false;
  2324. end;
  2325. function search_objc_method(const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
  2326. var
  2327. hashedid : THashedIDString;
  2328. stackitem : psymtablestackitem;
  2329. i : longint;
  2330. begin
  2331. hashedid.id:=class_helper_prefix+s;
  2332. stackitem:=symtablestack.stack;
  2333. while assigned(stackitem) do
  2334. begin
  2335. srsymtable:=stackitem^.symtable;
  2336. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2337. if assigned(srsym) then
  2338. begin
  2339. if not(srsymtable.symtabletype in [globalsymtable,staticsymtable]) or
  2340. not(srsym.owner.symtabletype in [globalsymtable,staticsymtable]) or
  2341. (srsym.typ<>procsym) then
  2342. internalerror(2009112005);
  2343. { check whether this procsym includes a helper for this particular class }
  2344. for i:=0 to tprocsym(srsym).procdeflist.count-1 do
  2345. begin
  2346. { we need to know if a procedure references symbols
  2347. in the static symtable, because then it can't be
  2348. inlined from outside this unit }
  2349. if assigned(current_procinfo) and
  2350. (srsym.owner.symtabletype=staticsymtable) then
  2351. include(current_procinfo.flags,pi_uses_static_symtable);
  2352. { no need to keep looking. There might be other
  2353. methods with the same name, but that doesn't matter
  2354. as far as the basic procsym is concerned.
  2355. }
  2356. srsym:=tprocdef(tprocsym(srsym).procdeflist[i]).procsym;
  2357. { We need the symtable in which the classhelper-like sym
  2358. is located, not the objectdef. The reason is that the
  2359. callnode will climb the symtablestack until it encounters
  2360. this symtable to start looking for overloads (and it won't
  2361. find the objectsymtable in which this method sym is
  2362. located
  2363. srsymtable:=srsym.owner;
  2364. }
  2365. addsymref(srsym);
  2366. result:=true;
  2367. exit;
  2368. end;
  2369. end;
  2370. stackitem:=stackitem^.next;
  2371. end;
  2372. srsym:=nil;
  2373. srsymtable:=nil;
  2374. result:=false;
  2375. end;
  2376. function search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
  2377. { searches n in symtable of pd and all anchestors }
  2378. var
  2379. hashedid : THashedIDString;
  2380. srsym : tsym;
  2381. orgpd : tabstractrecorddef;
  2382. srsymtable : tsymtable;
  2383. begin
  2384. { in case this is a formal objcclass, first find the real definition }
  2385. if (oo_is_formal in pd.objectoptions) then
  2386. pd:=find_real_objcclass_definition(tobjectdef(pd),true);
  2387. hashedid.id:=s;
  2388. orgpd:=pd;
  2389. while assigned(pd) do
  2390. begin
  2391. srsym:=tsym(pd.symtable.FindWithHash(hashedid));
  2392. if assigned(srsym) then
  2393. begin
  2394. search_struct_member:=srsym;
  2395. exit;
  2396. end;
  2397. if pd.typ=objectdef then
  2398. pd:=tobjectdef(pd).childof
  2399. else
  2400. pd:=nil;
  2401. end;
  2402. { not found, now look for class helpers }
  2403. if is_objcclass(pd) then
  2404. search_class_helper(tobjectdef(orgpd),s,result,srsymtable)
  2405. else
  2406. result:=nil;
  2407. end;
  2408. function search_macro(const s : string):tsym;
  2409. var
  2410. stackitem : psymtablestackitem;
  2411. hashedid : THashedIDString;
  2412. srsym : tsym;
  2413. begin
  2414. hashedid.id:=s;
  2415. { First search the localmacrosymtable before searching the
  2416. global macrosymtables from the units }
  2417. if assigned(current_module) then
  2418. begin
  2419. srsym:=tsym(current_module.localmacrosymtable.FindWithHash(hashedid));
  2420. if assigned(srsym) then
  2421. begin
  2422. result:= srsym;
  2423. exit;
  2424. end;
  2425. end;
  2426. stackitem:=macrosymtablestack.stack;
  2427. while assigned(stackitem) do
  2428. begin
  2429. srsym:=tsym(stackitem^.symtable.FindWithHash(hashedid));
  2430. if assigned(srsym) then
  2431. begin
  2432. result:= srsym;
  2433. exit;
  2434. end;
  2435. stackitem:=stackitem^.next;
  2436. end;
  2437. result:= nil;
  2438. end;
  2439. function defined_macro(const s : string):boolean;
  2440. var
  2441. mac: tmacro;
  2442. begin
  2443. mac:=tmacro(search_macro(s));
  2444. if assigned(mac) then
  2445. begin
  2446. mac.is_used:=true;
  2447. defined_macro:=mac.defined;
  2448. end
  2449. else
  2450. defined_macro:=false;
  2451. end;
  2452. {****************************************************************************
  2453. Object Helpers
  2454. ****************************************************************************}
  2455. function search_default_property(pd : tobjectdef) : tpropertysym;
  2456. { returns the default property of a class, searches also anchestors }
  2457. var
  2458. _defaultprop : tpropertysym;
  2459. begin
  2460. _defaultprop:=nil;
  2461. while assigned(pd) do
  2462. begin
  2463. pd.symtable.SymList.ForEachCall(@tstoredsymtable(pd.symtable).testfordefaultproperty,@_defaultprop);
  2464. if assigned(_defaultprop) then
  2465. break;
  2466. pd:=pd.childof;
  2467. end;
  2468. search_default_property:=_defaultprop;
  2469. end;
  2470. {****************************************************************************
  2471. Macro Helpers
  2472. ****************************************************************************}
  2473. procedure def_system_macro(const name : string);
  2474. var
  2475. mac : tmacro;
  2476. s: string;
  2477. begin
  2478. if name = '' then
  2479. internalerror(2004121202);
  2480. s:= upper(name);
  2481. mac:=tmacro(search_macro(s));
  2482. if not assigned(mac) then
  2483. begin
  2484. mac:=tmacro.create(s);
  2485. if assigned(current_module) then
  2486. current_module.localmacrosymtable.insert(mac)
  2487. else
  2488. initialmacrosymtable.insert(mac);
  2489. end;
  2490. if not mac.defined then
  2491. Message1(parser_c_macro_defined,mac.name);
  2492. mac.defined:=true;
  2493. end;
  2494. procedure set_system_macro(const name, value : string);
  2495. var
  2496. mac : tmacro;
  2497. s: string;
  2498. begin
  2499. if name = '' then
  2500. internalerror(2004121203);
  2501. s:= upper(name);
  2502. mac:=tmacro(search_macro(s));
  2503. if not assigned(mac) then
  2504. begin
  2505. mac:=tmacro.create(s);
  2506. if assigned(current_module) then
  2507. current_module.localmacrosymtable.insert(mac)
  2508. else
  2509. initialmacrosymtable.insert(mac);
  2510. end
  2511. else
  2512. begin
  2513. mac.is_compiler_var:=false;
  2514. if assigned(mac.buftext) then
  2515. freemem(mac.buftext,mac.buflen);
  2516. end;
  2517. Message2(parser_c_macro_set_to,mac.name,value);
  2518. mac.buflen:=length(value);
  2519. getmem(mac.buftext,mac.buflen);
  2520. move(value[1],mac.buftext^,mac.buflen);
  2521. mac.defined:=true;
  2522. end;
  2523. procedure set_system_compvar(const name, value : string);
  2524. var
  2525. mac : tmacro;
  2526. s: string;
  2527. begin
  2528. if name = '' then
  2529. internalerror(2004121204);
  2530. s:= upper(name);
  2531. mac:=tmacro(search_macro(s));
  2532. if not assigned(mac) then
  2533. begin
  2534. mac:=tmacro.create(s);
  2535. mac.is_compiler_var:=true;
  2536. if assigned(current_module) then
  2537. current_module.localmacrosymtable.insert(mac)
  2538. else
  2539. initialmacrosymtable.insert(mac);
  2540. end
  2541. else
  2542. begin
  2543. mac.is_compiler_var:=true;
  2544. if assigned(mac.buftext) then
  2545. freemem(mac.buftext,mac.buflen);
  2546. end;
  2547. Message2(parser_c_macro_set_to,mac.name,value);
  2548. mac.buflen:=length(value);
  2549. getmem(mac.buftext,mac.buflen);
  2550. move(value[1],mac.buftext^,mac.buflen);
  2551. mac.defined:=true;
  2552. end;
  2553. procedure undef_system_macro(const name : string);
  2554. var
  2555. mac : tmacro;
  2556. s: string;
  2557. begin
  2558. if name = '' then
  2559. internalerror(2004121205);
  2560. s:= upper(name);
  2561. mac:=tmacro(search_macro(s));
  2562. if not assigned(mac) then
  2563. {If not found, then it's already undefined.}
  2564. else
  2565. begin
  2566. if mac.defined then
  2567. Message1(parser_c_macro_undefined,mac.name);
  2568. mac.defined:=false;
  2569. mac.is_compiler_var:=false;
  2570. { delete old definition }
  2571. if assigned(mac.buftext) then
  2572. begin
  2573. freemem(mac.buftext,mac.buflen);
  2574. mac.buftext:=nil;
  2575. end;
  2576. end;
  2577. end;
  2578. {$ifdef UNITALIASES}
  2579. {****************************************************************************
  2580. TUNIT_ALIAS
  2581. ****************************************************************************}
  2582. constructor tunit_alias.create(const n:string);
  2583. var
  2584. i : longint;
  2585. begin
  2586. i:=pos('=',n);
  2587. if i=0 then
  2588. fail;
  2589. inherited createname(Copy(n,1,i-1));
  2590. newname:=stringdup(Copy(n,i+1,255));
  2591. end;
  2592. destructor tunit_alias.destroy;
  2593. begin
  2594. stringdispose(newname);
  2595. inherited destroy;
  2596. end;
  2597. procedure addunitalias(const n:string);
  2598. begin
  2599. unitaliases^.insert(tunit_alias,init(Upper(n))));
  2600. end;
  2601. function getunitalias(const n:string):string;
  2602. var
  2603. p : punit_alias;
  2604. begin
  2605. p:=punit_alias(unitaliases^.Find(Upper(n)));
  2606. if assigned(p) then
  2607. getunitalias:=punit_alias(p).newname^
  2608. else
  2609. getunitalias:=n;
  2610. end;
  2611. {$endif UNITALIASES}
  2612. {****************************************************************************
  2613. Init/Done Symtable
  2614. ****************************************************************************}
  2615. procedure InitSymtable;
  2616. begin
  2617. { Reset symbolstack }
  2618. symtablestack:=nil;
  2619. systemunit:=nil;
  2620. { create error syms and def }
  2621. generrorsym:=terrorsym.create;
  2622. generrordef:=terrordef.create;
  2623. { macros }
  2624. initialmacrosymtable:=tmacrosymtable.create(false);
  2625. macrosymtablestack:=TSymtablestack.create;
  2626. macrosymtablestack.push(initialmacrosymtable);
  2627. {$ifdef UNITALIASES}
  2628. { unit aliases }
  2629. unitaliases:=TFPHashObjectList.create;
  2630. {$endif}
  2631. { set some global vars to nil, might be important for the ide }
  2632. class_tobject:=nil;
  2633. interface_iunknown:=nil;
  2634. interface_idispatch:=nil;
  2635. rec_tguid:=nil;
  2636. dupnr:=0;
  2637. end;
  2638. procedure DoneSymtable;
  2639. begin
  2640. generrorsym.owner:=nil;
  2641. generrorsym.free;
  2642. generrordef.owner:=nil;
  2643. generrordef.free;
  2644. initialmacrosymtable.free;
  2645. macrosymtablestack.free;
  2646. {$ifdef UNITALIASES}
  2647. unitaliases.free;
  2648. {$endif}
  2649. end;
  2650. end.