symtable.pas 115 KB

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