MasmParser.cpp 255 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725
  1. //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This class implements the parser for assembly files.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/ADT/APFloat.h"
  13. #include "llvm/ADT/APInt.h"
  14. #include "llvm/ADT/ArrayRef.h"
  15. #include "llvm/ADT/BitVector.h"
  16. #include "llvm/ADT/STLExtras.h"
  17. #include "llvm/ADT/SmallString.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/ADT/StringExtras.h"
  20. #include "llvm/ADT/StringMap.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/ADT/StringSwitch.h"
  23. #include "llvm/ADT/Twine.h"
  24. #include "llvm/BinaryFormat/Dwarf.h"
  25. #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
  26. #include "llvm/MC/MCAsmInfo.h"
  27. #include "llvm/MC/MCCodeView.h"
  28. #include "llvm/MC/MCContext.h"
  29. #include "llvm/MC/MCDirectives.h"
  30. #include "llvm/MC/MCDwarf.h"
  31. #include "llvm/MC/MCExpr.h"
  32. #include "llvm/MC/MCInstPrinter.h"
  33. #include "llvm/MC/MCInstrDesc.h"
  34. #include "llvm/MC/MCInstrInfo.h"
  35. #include "llvm/MC/MCParser/AsmCond.h"
  36. #include "llvm/MC/MCParser/AsmLexer.h"
  37. #include "llvm/MC/MCParser/MCAsmLexer.h"
  38. #include "llvm/MC/MCParser/MCAsmParser.h"
  39. #include "llvm/MC/MCParser/MCAsmParserExtension.h"
  40. #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
  41. #include "llvm/MC/MCParser/MCTargetAsmParser.h"
  42. #include "llvm/MC/MCRegisterInfo.h"
  43. #include "llvm/MC/MCSection.h"
  44. #include "llvm/MC/MCStreamer.h"
  45. #include "llvm/MC/MCSubtargetInfo.h"
  46. #include "llvm/MC/MCSymbol.h"
  47. #include "llvm/MC/MCTargetOptions.h"
  48. #include "llvm/Support/Casting.h"
  49. #include "llvm/Support/CommandLine.h"
  50. #include "llvm/Support/ErrorHandling.h"
  51. #include "llvm/Support/Format.h"
  52. #include "llvm/Support/MD5.h"
  53. #include "llvm/Support/MathExtras.h"
  54. #include "llvm/Support/MemoryBuffer.h"
  55. #include "llvm/Support/Path.h"
  56. #include "llvm/Support/SMLoc.h"
  57. #include "llvm/Support/SourceMgr.h"
  58. #include "llvm/Support/raw_ostream.h"
  59. #include <algorithm>
  60. #include <cassert>
  61. #include <climits>
  62. #include <cstddef>
  63. #include <cstdint>
  64. #include <ctime>
  65. #include <deque>
  66. #include <memory>
  67. #include <optional>
  68. #include <sstream>
  69. #include <string>
  70. #include <tuple>
  71. #include <utility>
  72. #include <vector>
  73. using namespace llvm;
  74. namespace {
  75. /// Helper types for tracking macro definitions.
  76. typedef std::vector<AsmToken> MCAsmMacroArgument;
  77. typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
  78. /// Helper class for storing information about an active macro instantiation.
  79. struct MacroInstantiation {
  80. /// The location of the instantiation.
  81. SMLoc InstantiationLoc;
  82. /// The buffer where parsing should resume upon instantiation completion.
  83. unsigned ExitBuffer;
  84. /// The location where parsing should resume upon instantiation completion.
  85. SMLoc ExitLoc;
  86. /// The depth of TheCondStack at the start of the instantiation.
  87. size_t CondStackDepth;
  88. };
  89. struct ParseStatementInfo {
  90. /// The parsed operands from the last parsed statement.
  91. SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> ParsedOperands;
  92. /// The opcode from the last parsed instruction.
  93. unsigned Opcode = ~0U;
  94. /// Was there an error parsing the inline assembly?
  95. bool ParseError = false;
  96. /// The value associated with a macro exit.
  97. std::optional<std::string> ExitValue;
  98. SmallVectorImpl<AsmRewrite> *AsmRewrites = nullptr;
  99. ParseStatementInfo() = delete;
  100. ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
  101. : AsmRewrites(rewrites) {}
  102. };
  103. enum FieldType {
  104. FT_INTEGRAL, // Initializer: integer expression, stored as an MCExpr.
  105. FT_REAL, // Initializer: real number, stored as an APInt.
  106. FT_STRUCT // Initializer: struct initializer, stored recursively.
  107. };
  108. struct FieldInfo;
  109. struct StructInfo {
  110. StringRef Name;
  111. bool IsUnion = false;
  112. bool Initializable = true;
  113. unsigned Alignment = 0;
  114. unsigned AlignmentSize = 0;
  115. unsigned NextOffset = 0;
  116. unsigned Size = 0;
  117. std::vector<FieldInfo> Fields;
  118. StringMap<size_t> FieldsByName;
  119. FieldInfo &addField(StringRef FieldName, FieldType FT,
  120. unsigned FieldAlignmentSize);
  121. StructInfo() = default;
  122. StructInfo(StringRef StructName, bool Union, unsigned AlignmentValue);
  123. };
  124. // FIXME: This should probably use a class hierarchy, raw pointers between the
  125. // objects, and dynamic type resolution instead of a union. On the other hand,
  126. // ownership then becomes much more complicated; the obvious thing would be to
  127. // use BumpPtrAllocator, but the lack of a destructor makes that messy.
  128. struct StructInitializer;
  129. struct IntFieldInfo {
  130. SmallVector<const MCExpr *, 1> Values;
  131. IntFieldInfo() = default;
  132. IntFieldInfo(const SmallVector<const MCExpr *, 1> &V) { Values = V; }
  133. IntFieldInfo(SmallVector<const MCExpr *, 1> &&V) { Values = V; }
  134. };
  135. struct RealFieldInfo {
  136. SmallVector<APInt, 1> AsIntValues;
  137. RealFieldInfo() = default;
  138. RealFieldInfo(const SmallVector<APInt, 1> &V) { AsIntValues = V; }
  139. RealFieldInfo(SmallVector<APInt, 1> &&V) { AsIntValues = V; }
  140. };
  141. struct StructFieldInfo {
  142. std::vector<StructInitializer> Initializers;
  143. StructInfo Structure;
  144. StructFieldInfo() = default;
  145. StructFieldInfo(std::vector<StructInitializer> V, StructInfo S);
  146. };
  147. class FieldInitializer {
  148. public:
  149. FieldType FT;
  150. union {
  151. IntFieldInfo IntInfo;
  152. RealFieldInfo RealInfo;
  153. StructFieldInfo StructInfo;
  154. };
  155. ~FieldInitializer();
  156. FieldInitializer(FieldType FT);
  157. FieldInitializer(SmallVector<const MCExpr *, 1> &&Values);
  158. FieldInitializer(SmallVector<APInt, 1> &&AsIntValues);
  159. FieldInitializer(std::vector<StructInitializer> &&Initializers,
  160. struct StructInfo Structure);
  161. FieldInitializer(const FieldInitializer &Initializer);
  162. FieldInitializer(FieldInitializer &&Initializer);
  163. FieldInitializer &operator=(const FieldInitializer &Initializer);
  164. FieldInitializer &operator=(FieldInitializer &&Initializer);
  165. };
  166. struct StructInitializer {
  167. std::vector<FieldInitializer> FieldInitializers;
  168. };
  169. struct FieldInfo {
  170. // Offset of the field within the containing STRUCT.
  171. unsigned Offset = 0;
  172. // Total size of the field (= LengthOf * Type).
  173. unsigned SizeOf = 0;
  174. // Number of elements in the field (1 if scalar, >1 if an array).
  175. unsigned LengthOf = 0;
  176. // Size of a single entry in this field, in bytes ("type" in MASM standards).
  177. unsigned Type = 0;
  178. FieldInitializer Contents;
  179. FieldInfo(FieldType FT) : Contents(FT) {}
  180. };
  181. StructFieldInfo::StructFieldInfo(std::vector<StructInitializer> V,
  182. StructInfo S) {
  183. Initializers = std::move(V);
  184. Structure = S;
  185. }
  186. StructInfo::StructInfo(StringRef StructName, bool Union,
  187. unsigned AlignmentValue)
  188. : Name(StructName), IsUnion(Union), Alignment(AlignmentValue) {}
  189. FieldInfo &StructInfo::addField(StringRef FieldName, FieldType FT,
  190. unsigned FieldAlignmentSize) {
  191. if (!FieldName.empty())
  192. FieldsByName[FieldName.lower()] = Fields.size();
  193. Fields.emplace_back(FT);
  194. FieldInfo &Field = Fields.back();
  195. Field.Offset =
  196. llvm::alignTo(NextOffset, std::min(Alignment, FieldAlignmentSize));
  197. if (!IsUnion) {
  198. NextOffset = std::max(NextOffset, Field.Offset);
  199. }
  200. AlignmentSize = std::max(AlignmentSize, FieldAlignmentSize);
  201. return Field;
  202. }
  203. FieldInitializer::~FieldInitializer() {
  204. switch (FT) {
  205. case FT_INTEGRAL:
  206. IntInfo.~IntFieldInfo();
  207. break;
  208. case FT_REAL:
  209. RealInfo.~RealFieldInfo();
  210. break;
  211. case FT_STRUCT:
  212. StructInfo.~StructFieldInfo();
  213. break;
  214. }
  215. }
  216. FieldInitializer::FieldInitializer(FieldType FT) : FT(FT) {
  217. switch (FT) {
  218. case FT_INTEGRAL:
  219. new (&IntInfo) IntFieldInfo();
  220. break;
  221. case FT_REAL:
  222. new (&RealInfo) RealFieldInfo();
  223. break;
  224. case FT_STRUCT:
  225. new (&StructInfo) StructFieldInfo();
  226. break;
  227. }
  228. }
  229. FieldInitializer::FieldInitializer(SmallVector<const MCExpr *, 1> &&Values)
  230. : FT(FT_INTEGRAL) {
  231. new (&IntInfo) IntFieldInfo(Values);
  232. }
  233. FieldInitializer::FieldInitializer(SmallVector<APInt, 1> &&AsIntValues)
  234. : FT(FT_REAL) {
  235. new (&RealInfo) RealFieldInfo(AsIntValues);
  236. }
  237. FieldInitializer::FieldInitializer(
  238. std::vector<StructInitializer> &&Initializers, struct StructInfo Structure)
  239. : FT(FT_STRUCT) {
  240. new (&StructInfo) StructFieldInfo(std::move(Initializers), Structure);
  241. }
  242. FieldInitializer::FieldInitializer(const FieldInitializer &Initializer)
  243. : FT(Initializer.FT) {
  244. switch (FT) {
  245. case FT_INTEGRAL:
  246. new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
  247. break;
  248. case FT_REAL:
  249. new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
  250. break;
  251. case FT_STRUCT:
  252. new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
  253. break;
  254. }
  255. }
  256. FieldInitializer::FieldInitializer(FieldInitializer &&Initializer)
  257. : FT(Initializer.FT) {
  258. switch (FT) {
  259. case FT_INTEGRAL:
  260. new (&IntInfo) IntFieldInfo(Initializer.IntInfo);
  261. break;
  262. case FT_REAL:
  263. new (&RealInfo) RealFieldInfo(Initializer.RealInfo);
  264. break;
  265. case FT_STRUCT:
  266. new (&StructInfo) StructFieldInfo(Initializer.StructInfo);
  267. break;
  268. }
  269. }
  270. FieldInitializer &
  271. FieldInitializer::operator=(const FieldInitializer &Initializer) {
  272. if (FT != Initializer.FT) {
  273. switch (FT) {
  274. case FT_INTEGRAL:
  275. IntInfo.~IntFieldInfo();
  276. break;
  277. case FT_REAL:
  278. RealInfo.~RealFieldInfo();
  279. break;
  280. case FT_STRUCT:
  281. StructInfo.~StructFieldInfo();
  282. break;
  283. }
  284. }
  285. FT = Initializer.FT;
  286. switch (FT) {
  287. case FT_INTEGRAL:
  288. IntInfo = Initializer.IntInfo;
  289. break;
  290. case FT_REAL:
  291. RealInfo = Initializer.RealInfo;
  292. break;
  293. case FT_STRUCT:
  294. StructInfo = Initializer.StructInfo;
  295. break;
  296. }
  297. return *this;
  298. }
  299. FieldInitializer &FieldInitializer::operator=(FieldInitializer &&Initializer) {
  300. if (FT != Initializer.FT) {
  301. switch (FT) {
  302. case FT_INTEGRAL:
  303. IntInfo.~IntFieldInfo();
  304. break;
  305. case FT_REAL:
  306. RealInfo.~RealFieldInfo();
  307. break;
  308. case FT_STRUCT:
  309. StructInfo.~StructFieldInfo();
  310. break;
  311. }
  312. }
  313. FT = Initializer.FT;
  314. switch (FT) {
  315. case FT_INTEGRAL:
  316. IntInfo = Initializer.IntInfo;
  317. break;
  318. case FT_REAL:
  319. RealInfo = Initializer.RealInfo;
  320. break;
  321. case FT_STRUCT:
  322. StructInfo = Initializer.StructInfo;
  323. break;
  324. }
  325. return *this;
  326. }
  327. /// The concrete assembly parser instance.
  328. // Note that this is a full MCAsmParser, not an MCAsmParserExtension!
  329. // It's a peer of AsmParser, not of COFFAsmParser, WasmAsmParser, etc.
  330. class MasmParser : public MCAsmParser {
  331. private:
  332. AsmLexer Lexer;
  333. MCContext &Ctx;
  334. MCStreamer &Out;
  335. const MCAsmInfo &MAI;
  336. SourceMgr &SrcMgr;
  337. SourceMgr::DiagHandlerTy SavedDiagHandler;
  338. void *SavedDiagContext;
  339. std::unique_ptr<MCAsmParserExtension> PlatformParser;
  340. /// This is the current buffer index we're lexing from as managed by the
  341. /// SourceMgr object.
  342. unsigned CurBuffer;
  343. /// time of assembly
  344. struct tm TM;
  345. BitVector EndStatementAtEOFStack;
  346. AsmCond TheCondState;
  347. std::vector<AsmCond> TheCondStack;
  348. /// maps directive names to handler methods in parser
  349. /// extensions. Extensions register themselves in this map by calling
  350. /// addDirectiveHandler.
  351. StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
  352. /// maps assembly-time variable names to variables.
  353. struct Variable {
  354. enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE };
  355. StringRef Name;
  356. RedefinableKind Redefinable = REDEFINABLE;
  357. bool IsText = false;
  358. std::string TextValue;
  359. };
  360. StringMap<Variable> Variables;
  361. /// Stack of active struct definitions.
  362. SmallVector<StructInfo, 1> StructInProgress;
  363. /// Maps struct tags to struct definitions.
  364. StringMap<StructInfo> Structs;
  365. /// Maps data location names to types.
  366. StringMap<AsmTypeInfo> KnownType;
  367. /// Stack of active macro instantiations.
  368. std::vector<MacroInstantiation*> ActiveMacros;
  369. /// List of bodies of anonymous macros.
  370. std::deque<MCAsmMacro> MacroLikeBodies;
  371. /// Keeps track of how many .macro's have been instantiated.
  372. unsigned NumOfMacroInstantiations;
  373. /// The values from the last parsed cpp hash file line comment if any.
  374. struct CppHashInfoTy {
  375. StringRef Filename;
  376. int64_t LineNumber;
  377. SMLoc Loc;
  378. unsigned Buf;
  379. CppHashInfoTy() : LineNumber(0), Buf(0) {}
  380. };
  381. CppHashInfoTy CppHashInfo;
  382. /// The filename from the first cpp hash file line comment, if any.
  383. StringRef FirstCppHashFilename;
  384. /// List of forward directional labels for diagnosis at the end.
  385. SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
  386. /// AssemblerDialect. ~OU means unset value and use value provided by MAI.
  387. /// Defaults to 1U, meaning Intel.
  388. unsigned AssemblerDialect = 1U;
  389. /// is Darwin compatibility enabled?
  390. bool IsDarwin = false;
  391. /// Are we parsing ms-style inline assembly?
  392. bool ParsingMSInlineAsm = false;
  393. /// Did we already inform the user about inconsistent MD5 usage?
  394. bool ReportedInconsistentMD5 = false;
  395. // Current <...> expression depth.
  396. unsigned AngleBracketDepth = 0U;
  397. // Number of locals defined.
  398. uint16_t LocalCounter = 0;
  399. public:
  400. MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
  401. const MCAsmInfo &MAI, struct tm TM, unsigned CB = 0);
  402. MasmParser(const MasmParser &) = delete;
  403. MasmParser &operator=(const MasmParser &) = delete;
  404. ~MasmParser() override;
  405. bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
  406. void addDirectiveHandler(StringRef Directive,
  407. ExtensionDirectiveHandler Handler) override {
  408. ExtensionDirectiveMap[Directive] = Handler;
  409. if (DirectiveKindMap.find(Directive) == DirectiveKindMap.end()) {
  410. DirectiveKindMap[Directive] = DK_HANDLER_DIRECTIVE;
  411. }
  412. }
  413. void addAliasForDirective(StringRef Directive, StringRef Alias) override {
  414. DirectiveKindMap[Directive] = DirectiveKindMap[Alias];
  415. }
  416. /// @name MCAsmParser Interface
  417. /// {
  418. SourceMgr &getSourceManager() override { return SrcMgr; }
  419. MCAsmLexer &getLexer() override { return Lexer; }
  420. MCContext &getContext() override { return Ctx; }
  421. MCStreamer &getStreamer() override { return Out; }
  422. CodeViewContext &getCVContext() { return Ctx.getCVContext(); }
  423. unsigned getAssemblerDialect() override {
  424. if (AssemblerDialect == ~0U)
  425. return MAI.getAssemblerDialect();
  426. else
  427. return AssemblerDialect;
  428. }
  429. void setAssemblerDialect(unsigned i) override {
  430. AssemblerDialect = i;
  431. }
  432. void Note(SMLoc L, const Twine &Msg, SMRange Range = std::nullopt) override;
  433. bool Warning(SMLoc L, const Twine &Msg,
  434. SMRange Range = std::nullopt) override;
  435. bool printError(SMLoc L, const Twine &Msg,
  436. SMRange Range = std::nullopt) override;
  437. enum ExpandKind { ExpandMacros, DoNotExpandMacros };
  438. const AsmToken &Lex(ExpandKind ExpandNextToken);
  439. const AsmToken &Lex() override { return Lex(ExpandMacros); }
  440. void setParsingMSInlineAsm(bool V) override {
  441. ParsingMSInlineAsm = V;
  442. // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and
  443. // hex integer literals.
  444. Lexer.setLexMasmIntegers(V);
  445. }
  446. bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; }
  447. bool isParsingMasm() const override { return true; }
  448. bool defineMacro(StringRef Name, StringRef Value) override;
  449. bool lookUpField(StringRef Name, AsmFieldInfo &Info) const override;
  450. bool lookUpField(StringRef Base, StringRef Member,
  451. AsmFieldInfo &Info) const override;
  452. bool lookUpType(StringRef Name, AsmTypeInfo &Info) const override;
  453. bool parseMSInlineAsm(std::string &AsmString, unsigned &NumOutputs,
  454. unsigned &NumInputs,
  455. SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
  456. SmallVectorImpl<std::string> &Constraints,
  457. SmallVectorImpl<std::string> &Clobbers,
  458. const MCInstrInfo *MII, const MCInstPrinter *IP,
  459. MCAsmParserSemaCallback &SI) override;
  460. bool parseExpression(const MCExpr *&Res);
  461. bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
  462. bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
  463. AsmTypeInfo *TypeInfo) override;
  464. bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override;
  465. bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
  466. SMLoc &EndLoc) override;
  467. bool parseAbsoluteExpression(int64_t &Res) override;
  468. /// Parse a floating point expression using the float \p Semantics
  469. /// and set \p Res to the value.
  470. bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
  471. /// Parse an identifier or string (as a quoted identifier)
  472. /// and set \p Res to the identifier contents.
  473. enum IdentifierPositionKind { StandardPosition, StartOfStatement };
  474. bool parseIdentifier(StringRef &Res, IdentifierPositionKind Position);
  475. bool parseIdentifier(StringRef &Res) override {
  476. return parseIdentifier(Res, StandardPosition);
  477. }
  478. void eatToEndOfStatement() override;
  479. bool checkForValidSection() override;
  480. /// }
  481. private:
  482. bool expandMacros();
  483. const AsmToken peekTok(bool ShouldSkipSpace = true);
  484. bool parseStatement(ParseStatementInfo &Info,
  485. MCAsmParserSemaCallback *SI);
  486. bool parseCurlyBlockScope(SmallVectorImpl<AsmRewrite>& AsmStrRewrites);
  487. bool parseCppHashLineFilenameComment(SMLoc L);
  488. bool expandMacro(raw_svector_ostream &OS, StringRef Body,
  489. ArrayRef<MCAsmMacroParameter> Parameters,
  490. ArrayRef<MCAsmMacroArgument> A,
  491. const std::vector<std::string> &Locals, SMLoc L);
  492. /// Are we inside a macro instantiation?
  493. bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
  494. /// Handle entry to macro instantiation.
  495. ///
  496. /// \param M The macro.
  497. /// \param NameLoc Instantiation location.
  498. bool handleMacroEntry(
  499. const MCAsmMacro *M, SMLoc NameLoc,
  500. AsmToken::TokenKind ArgumentEndTok = AsmToken::EndOfStatement);
  501. /// Handle invocation of macro function.
  502. ///
  503. /// \param M The macro.
  504. /// \param NameLoc Invocation location.
  505. bool handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc);
  506. /// Handle exit from macro instantiation.
  507. void handleMacroExit();
  508. /// Extract AsmTokens for a macro argument.
  509. bool
  510. parseMacroArgument(const MCAsmMacroParameter *MP, MCAsmMacroArgument &MA,
  511. AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
  512. /// Parse all macro arguments for a given macro.
  513. bool
  514. parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A,
  515. AsmToken::TokenKind EndTok = AsmToken::EndOfStatement);
  516. void printMacroInstantiations();
  517. bool expandStatement(SMLoc Loc);
  518. void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
  519. SMRange Range = std::nullopt) const {
  520. ArrayRef<SMRange> Ranges(Range);
  521. SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges);
  522. }
  523. static void DiagHandler(const SMDiagnostic &Diag, void *Context);
  524. bool lookUpField(const StructInfo &Structure, StringRef Member,
  525. AsmFieldInfo &Info) const;
  526. /// Should we emit DWARF describing this assembler source? (Returns false if
  527. /// the source has .file directives, which means we don't want to generate
  528. /// info describing the assembler source itself.)
  529. bool enabledGenDwarfForAssembly();
  530. /// Enter the specified file. This returns true on failure.
  531. bool enterIncludeFile(const std::string &Filename);
  532. /// Reset the current lexer position to that given by \p Loc. The
  533. /// current token is not set; clients should ensure Lex() is called
  534. /// subsequently.
  535. ///
  536. /// \param InBuffer If not 0, should be the known buffer id that contains the
  537. /// location.
  538. void jumpToLoc(SMLoc Loc, unsigned InBuffer = 0,
  539. bool EndStatementAtEOF = true);
  540. /// Parse up to a token of kind \p EndTok and return the contents from the
  541. /// current token up to (but not including) this token; the current token on
  542. /// exit will be either this kind or EOF. Reads through instantiated macro
  543. /// functions and text macros.
  544. SmallVector<StringRef, 1> parseStringRefsTo(AsmToken::TokenKind EndTok);
  545. std::string parseStringTo(AsmToken::TokenKind EndTok);
  546. /// Parse up to the end of statement and return the contents from the current
  547. /// token until the end of the statement; the current token on exit will be
  548. /// either the EndOfStatement or EOF.
  549. StringRef parseStringToEndOfStatement() override;
  550. bool parseTextItem(std::string &Data);
  551. unsigned getBinOpPrecedence(AsmToken::TokenKind K,
  552. MCBinaryExpr::Opcode &Kind);
  553. bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
  554. bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
  555. bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
  556. bool parseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
  557. bool parseCVFunctionId(int64_t &FunctionId, StringRef DirectiveName);
  558. bool parseCVFileId(int64_t &FileId, StringRef DirectiveName);
  559. // Generic (target and platform independent) directive parsing.
  560. enum DirectiveKind {
  561. DK_NO_DIRECTIVE, // Placeholder
  562. DK_HANDLER_DIRECTIVE,
  563. DK_ASSIGN,
  564. DK_EQU,
  565. DK_TEXTEQU,
  566. DK_ASCII,
  567. DK_ASCIZ,
  568. DK_STRING,
  569. DK_BYTE,
  570. DK_SBYTE,
  571. DK_WORD,
  572. DK_SWORD,
  573. DK_DWORD,
  574. DK_SDWORD,
  575. DK_FWORD,
  576. DK_QWORD,
  577. DK_SQWORD,
  578. DK_DB,
  579. DK_DD,
  580. DK_DF,
  581. DK_DQ,
  582. DK_DW,
  583. DK_REAL4,
  584. DK_REAL8,
  585. DK_REAL10,
  586. DK_ALIGN,
  587. DK_EVEN,
  588. DK_ORG,
  589. DK_ENDR,
  590. DK_EXTERN,
  591. DK_PUBLIC,
  592. DK_COMM,
  593. DK_COMMENT,
  594. DK_INCLUDE,
  595. DK_REPEAT,
  596. DK_WHILE,
  597. DK_FOR,
  598. DK_FORC,
  599. DK_IF,
  600. DK_IFE,
  601. DK_IFB,
  602. DK_IFNB,
  603. DK_IFDEF,
  604. DK_IFNDEF,
  605. DK_IFDIF,
  606. DK_IFDIFI,
  607. DK_IFIDN,
  608. DK_IFIDNI,
  609. DK_ELSEIF,
  610. DK_ELSEIFE,
  611. DK_ELSEIFB,
  612. DK_ELSEIFNB,
  613. DK_ELSEIFDEF,
  614. DK_ELSEIFNDEF,
  615. DK_ELSEIFDIF,
  616. DK_ELSEIFDIFI,
  617. DK_ELSEIFIDN,
  618. DK_ELSEIFIDNI,
  619. DK_ELSE,
  620. DK_ENDIF,
  621. DK_FILE,
  622. DK_LINE,
  623. DK_LOC,
  624. DK_STABS,
  625. DK_CV_FILE,
  626. DK_CV_FUNC_ID,
  627. DK_CV_INLINE_SITE_ID,
  628. DK_CV_LOC,
  629. DK_CV_LINETABLE,
  630. DK_CV_INLINE_LINETABLE,
  631. DK_CV_DEF_RANGE,
  632. DK_CV_STRINGTABLE,
  633. DK_CV_STRING,
  634. DK_CV_FILECHECKSUMS,
  635. DK_CV_FILECHECKSUM_OFFSET,
  636. DK_CV_FPO_DATA,
  637. DK_CFI_SECTIONS,
  638. DK_CFI_STARTPROC,
  639. DK_CFI_ENDPROC,
  640. DK_CFI_DEF_CFA,
  641. DK_CFI_DEF_CFA_OFFSET,
  642. DK_CFI_ADJUST_CFA_OFFSET,
  643. DK_CFI_DEF_CFA_REGISTER,
  644. DK_CFI_OFFSET,
  645. DK_CFI_REL_OFFSET,
  646. DK_CFI_PERSONALITY,
  647. DK_CFI_LSDA,
  648. DK_CFI_REMEMBER_STATE,
  649. DK_CFI_RESTORE_STATE,
  650. DK_CFI_SAME_VALUE,
  651. DK_CFI_RESTORE,
  652. DK_CFI_ESCAPE,
  653. DK_CFI_RETURN_COLUMN,
  654. DK_CFI_SIGNAL_FRAME,
  655. DK_CFI_UNDEFINED,
  656. DK_CFI_REGISTER,
  657. DK_CFI_WINDOW_SAVE,
  658. DK_CFI_B_KEY_FRAME,
  659. DK_MACRO,
  660. DK_EXITM,
  661. DK_ENDM,
  662. DK_PURGE,
  663. DK_ERR,
  664. DK_ERRB,
  665. DK_ERRNB,
  666. DK_ERRDEF,
  667. DK_ERRNDEF,
  668. DK_ERRDIF,
  669. DK_ERRDIFI,
  670. DK_ERRIDN,
  671. DK_ERRIDNI,
  672. DK_ERRE,
  673. DK_ERRNZ,
  674. DK_ECHO,
  675. DK_STRUCT,
  676. DK_UNION,
  677. DK_ENDS,
  678. DK_END,
  679. DK_PUSHFRAME,
  680. DK_PUSHREG,
  681. DK_SAVEREG,
  682. DK_SAVEXMM128,
  683. DK_SETFRAME,
  684. DK_RADIX,
  685. };
  686. /// Maps directive name --> DirectiveKind enum, for directives parsed by this
  687. /// class.
  688. StringMap<DirectiveKind> DirectiveKindMap;
  689. bool isMacroLikeDirective();
  690. // Codeview def_range type parsing.
  691. enum CVDefRangeType {
  692. CVDR_DEFRANGE = 0, // Placeholder
  693. CVDR_DEFRANGE_REGISTER,
  694. CVDR_DEFRANGE_FRAMEPOINTER_REL,
  695. CVDR_DEFRANGE_SUBFIELD_REGISTER,
  696. CVDR_DEFRANGE_REGISTER_REL
  697. };
  698. /// Maps Codeview def_range types --> CVDefRangeType enum, for Codeview
  699. /// def_range types parsed by this class.
  700. StringMap<CVDefRangeType> CVDefRangeTypeMap;
  701. // Generic (target and platform independent) directive parsing.
  702. enum BuiltinSymbol {
  703. BI_NO_SYMBOL, // Placeholder
  704. BI_DATE,
  705. BI_TIME,
  706. BI_VERSION,
  707. BI_FILECUR,
  708. BI_FILENAME,
  709. BI_LINE,
  710. BI_CURSEG,
  711. BI_CPU,
  712. BI_INTERFACE,
  713. BI_CODE,
  714. BI_DATA,
  715. BI_FARDATA,
  716. BI_WORDSIZE,
  717. BI_CODESIZE,
  718. BI_DATASIZE,
  719. BI_MODEL,
  720. BI_STACK,
  721. };
  722. /// Maps builtin name --> BuiltinSymbol enum, for builtins handled by this
  723. /// class.
  724. StringMap<BuiltinSymbol> BuiltinSymbolMap;
  725. const MCExpr *evaluateBuiltinValue(BuiltinSymbol Symbol, SMLoc StartLoc);
  726. std::optional<std::string> evaluateBuiltinTextMacro(BuiltinSymbol Symbol,
  727. SMLoc StartLoc);
  728. // ".ascii", ".asciz", ".string"
  729. bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
  730. // "byte", "word", ...
  731. bool emitIntValue(const MCExpr *Value, unsigned Size);
  732. bool parseScalarInitializer(unsigned Size,
  733. SmallVectorImpl<const MCExpr *> &Values,
  734. unsigned StringPadLength = 0);
  735. bool parseScalarInstList(
  736. unsigned Size, SmallVectorImpl<const MCExpr *> &Values,
  737. const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
  738. bool emitIntegralValues(unsigned Size, unsigned *Count = nullptr);
  739. bool addIntegralField(StringRef Name, unsigned Size);
  740. bool parseDirectiveValue(StringRef IDVal, unsigned Size);
  741. bool parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
  742. StringRef Name, SMLoc NameLoc);
  743. // "real4", "real8", "real10"
  744. bool emitRealValues(const fltSemantics &Semantics, unsigned *Count = nullptr);
  745. bool addRealField(StringRef Name, const fltSemantics &Semantics, size_t Size);
  746. bool parseDirectiveRealValue(StringRef IDVal, const fltSemantics &Semantics,
  747. size_t Size);
  748. bool parseRealInstList(
  749. const fltSemantics &Semantics, SmallVectorImpl<APInt> &Values,
  750. const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
  751. bool parseDirectiveNamedRealValue(StringRef TypeName,
  752. const fltSemantics &Semantics,
  753. unsigned Size, StringRef Name,
  754. SMLoc NameLoc);
  755. bool parseOptionalAngleBracketOpen();
  756. bool parseAngleBracketClose(const Twine &Msg = "expected '>'");
  757. bool parseFieldInitializer(const FieldInfo &Field,
  758. FieldInitializer &Initializer);
  759. bool parseFieldInitializer(const FieldInfo &Field,
  760. const IntFieldInfo &Contents,
  761. FieldInitializer &Initializer);
  762. bool parseFieldInitializer(const FieldInfo &Field,
  763. const RealFieldInfo &Contents,
  764. FieldInitializer &Initializer);
  765. bool parseFieldInitializer(const FieldInfo &Field,
  766. const StructFieldInfo &Contents,
  767. FieldInitializer &Initializer);
  768. bool parseStructInitializer(const StructInfo &Structure,
  769. StructInitializer &Initializer);
  770. bool parseStructInstList(
  771. const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
  772. const AsmToken::TokenKind EndToken = AsmToken::EndOfStatement);
  773. bool emitFieldValue(const FieldInfo &Field);
  774. bool emitFieldValue(const FieldInfo &Field, const IntFieldInfo &Contents);
  775. bool emitFieldValue(const FieldInfo &Field, const RealFieldInfo &Contents);
  776. bool emitFieldValue(const FieldInfo &Field, const StructFieldInfo &Contents);
  777. bool emitFieldInitializer(const FieldInfo &Field,
  778. const FieldInitializer &Initializer);
  779. bool emitFieldInitializer(const FieldInfo &Field,
  780. const IntFieldInfo &Contents,
  781. const IntFieldInfo &Initializer);
  782. bool emitFieldInitializer(const FieldInfo &Field,
  783. const RealFieldInfo &Contents,
  784. const RealFieldInfo &Initializer);
  785. bool emitFieldInitializer(const FieldInfo &Field,
  786. const StructFieldInfo &Contents,
  787. const StructFieldInfo &Initializer);
  788. bool emitStructInitializer(const StructInfo &Structure,
  789. const StructInitializer &Initializer);
  790. // User-defined types (structs, unions):
  791. bool emitStructValues(const StructInfo &Structure, unsigned *Count = nullptr);
  792. bool addStructField(StringRef Name, const StructInfo &Structure);
  793. bool parseDirectiveStructValue(const StructInfo &Structure,
  794. StringRef Directive, SMLoc DirLoc);
  795. bool parseDirectiveNamedStructValue(const StructInfo &Structure,
  796. StringRef Directive, SMLoc DirLoc,
  797. StringRef Name);
  798. // "=", "equ", "textequ"
  799. bool parseDirectiveEquate(StringRef IDVal, StringRef Name,
  800. DirectiveKind DirKind, SMLoc NameLoc);
  801. bool parseDirectiveOrg(); // "org"
  802. bool emitAlignTo(int64_t Alignment);
  803. bool parseDirectiveAlign(); // "align"
  804. bool parseDirectiveEven(); // "even"
  805. // ".file", ".line", ".loc", ".stabs"
  806. bool parseDirectiveFile(SMLoc DirectiveLoc);
  807. bool parseDirectiveLine();
  808. bool parseDirectiveLoc();
  809. bool parseDirectiveStabs();
  810. // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
  811. // ".cv_inline_linetable", ".cv_def_range", ".cv_string"
  812. bool parseDirectiveCVFile();
  813. bool parseDirectiveCVFuncId();
  814. bool parseDirectiveCVInlineSiteId();
  815. bool parseDirectiveCVLoc();
  816. bool parseDirectiveCVLinetable();
  817. bool parseDirectiveCVInlineLinetable();
  818. bool parseDirectiveCVDefRange();
  819. bool parseDirectiveCVString();
  820. bool parseDirectiveCVStringTable();
  821. bool parseDirectiveCVFileChecksums();
  822. bool parseDirectiveCVFileChecksumOffset();
  823. bool parseDirectiveCVFPOData();
  824. // .cfi directives
  825. bool parseDirectiveCFIRegister(SMLoc DirectiveLoc);
  826. bool parseDirectiveCFIWindowSave();
  827. bool parseDirectiveCFISections();
  828. bool parseDirectiveCFIStartProc();
  829. bool parseDirectiveCFIEndProc();
  830. bool parseDirectiveCFIDefCfaOffset();
  831. bool parseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
  832. bool parseDirectiveCFIAdjustCfaOffset();
  833. bool parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
  834. bool parseDirectiveCFIOffset(SMLoc DirectiveLoc);
  835. bool parseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
  836. bool parseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
  837. bool parseDirectiveCFIRememberState();
  838. bool parseDirectiveCFIRestoreState();
  839. bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
  840. bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
  841. bool parseDirectiveCFIEscape();
  842. bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
  843. bool parseDirectiveCFISignalFrame();
  844. bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
  845. // macro directives
  846. bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
  847. bool parseDirectiveExitMacro(SMLoc DirectiveLoc, StringRef Directive,
  848. std::string &Value);
  849. bool parseDirectiveEndMacro(StringRef Directive);
  850. bool parseDirectiveMacro(StringRef Name, SMLoc NameLoc);
  851. bool parseDirectiveStruct(StringRef Directive, DirectiveKind DirKind,
  852. StringRef Name, SMLoc NameLoc);
  853. bool parseDirectiveNestedStruct(StringRef Directive, DirectiveKind DirKind);
  854. bool parseDirectiveEnds(StringRef Name, SMLoc NameLoc);
  855. bool parseDirectiveNestedEnds();
  856. bool parseDirectiveExtern();
  857. /// Parse a directive like ".globl" which accepts a single symbol (which
  858. /// should be a label or an external).
  859. bool parseDirectiveSymbolAttribute(MCSymbolAttr Attr);
  860. bool parseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm"
  861. bool parseDirectiveComment(SMLoc DirectiveLoc); // "comment"
  862. bool parseDirectiveInclude(); // "include"
  863. // "if" or "ife"
  864. bool parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
  865. // "ifb" or "ifnb", depending on ExpectBlank.
  866. bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank);
  867. // "ifidn", "ifdif", "ifidni", or "ifdifi", depending on ExpectEqual and
  868. // CaseInsensitive.
  869. bool parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  870. bool CaseInsensitive);
  871. // "ifdef" or "ifndef", depending on expect_defined
  872. bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined);
  873. // "elseif" or "elseife"
  874. bool parseDirectiveElseIf(SMLoc DirectiveLoc, DirectiveKind DirKind);
  875. // "elseifb" or "elseifnb", depending on ExpectBlank.
  876. bool parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank);
  877. // ".elseifdef" or ".elseifndef", depending on expect_defined
  878. bool parseDirectiveElseIfdef(SMLoc DirectiveLoc, bool expect_defined);
  879. // "elseifidn", "elseifdif", "elseifidni", or "elseifdifi", depending on
  880. // ExpectEqual and CaseInsensitive.
  881. bool parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  882. bool CaseInsensitive);
  883. bool parseDirectiveElse(SMLoc DirectiveLoc); // "else"
  884. bool parseDirectiveEndIf(SMLoc DirectiveLoc); // "endif"
  885. bool parseEscapedString(std::string &Data) override;
  886. bool parseAngleBracketString(std::string &Data) override;
  887. // Macro-like directives
  888. MCAsmMacro *parseMacroLikeBody(SMLoc DirectiveLoc);
  889. void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
  890. raw_svector_ostream &OS);
  891. void instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
  892. SMLoc ExitLoc, raw_svector_ostream &OS);
  893. bool parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Directive);
  894. bool parseDirectiveFor(SMLoc DirectiveLoc, StringRef Directive);
  895. bool parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive);
  896. bool parseDirectiveWhile(SMLoc DirectiveLoc);
  897. // "_emit" or "__emit"
  898. bool parseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
  899. size_t Len);
  900. // "align"
  901. bool parseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
  902. // "end"
  903. bool parseDirectiveEnd(SMLoc DirectiveLoc);
  904. // ".err"
  905. bool parseDirectiveError(SMLoc DirectiveLoc);
  906. // ".errb" or ".errnb", depending on ExpectBlank.
  907. bool parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank);
  908. // ".errdef" or ".errndef", depending on ExpectBlank.
  909. bool parseDirectiveErrorIfdef(SMLoc DirectiveLoc, bool ExpectDefined);
  910. // ".erridn", ".errdif", ".erridni", or ".errdifi", depending on ExpectEqual
  911. // and CaseInsensitive.
  912. bool parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  913. bool CaseInsensitive);
  914. // ".erre" or ".errnz", depending on ExpectZero.
  915. bool parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero);
  916. // ".radix"
  917. bool parseDirectiveRadix(SMLoc DirectiveLoc);
  918. // "echo"
  919. bool parseDirectiveEcho(SMLoc DirectiveLoc);
  920. void initializeDirectiveKindMap();
  921. void initializeCVDefRangeTypeMap();
  922. void initializeBuiltinSymbolMap();
  923. };
  924. } // end anonymous namespace
  925. namespace llvm {
  926. extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
  927. extern MCAsmParserExtension *createCOFFMasmParser();
  928. } // end namespace llvm
  929. enum { DEFAULT_ADDRSPACE = 0 };
  930. MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
  931. const MCAsmInfo &MAI, struct tm TM, unsigned CB)
  932. : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
  933. CurBuffer(CB ? CB : SM.getMainFileID()), TM(TM) {
  934. HadError = false;
  935. // Save the old handler.
  936. SavedDiagHandler = SrcMgr.getDiagHandler();
  937. SavedDiagContext = SrcMgr.getDiagContext();
  938. // Set our own handler which calls the saved handler.
  939. SrcMgr.setDiagHandler(DiagHandler, this);
  940. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
  941. EndStatementAtEOFStack.push_back(true);
  942. // Initialize the platform / file format parser.
  943. switch (Ctx.getObjectFileType()) {
  944. case MCContext::IsCOFF:
  945. PlatformParser.reset(createCOFFMasmParser());
  946. break;
  947. default:
  948. report_fatal_error("llvm-ml currently supports only COFF output.");
  949. break;
  950. }
  951. initializeDirectiveKindMap();
  952. PlatformParser->Initialize(*this);
  953. initializeCVDefRangeTypeMap();
  954. initializeBuiltinSymbolMap();
  955. NumOfMacroInstantiations = 0;
  956. }
  957. MasmParser::~MasmParser() {
  958. assert((HadError || ActiveMacros.empty()) &&
  959. "Unexpected active macro instantiation!");
  960. // Restore the saved diagnostics handler and context for use during
  961. // finalization.
  962. SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
  963. }
  964. void MasmParser::printMacroInstantiations() {
  965. // Print the active macro instantiation stack.
  966. for (std::vector<MacroInstantiation *>::const_reverse_iterator
  967. it = ActiveMacros.rbegin(),
  968. ie = ActiveMacros.rend();
  969. it != ie; ++it)
  970. printMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
  971. "while in macro instantiation");
  972. }
  973. void MasmParser::Note(SMLoc L, const Twine &Msg, SMRange Range) {
  974. printPendingErrors();
  975. printMessage(L, SourceMgr::DK_Note, Msg, Range);
  976. printMacroInstantiations();
  977. }
  978. bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
  979. if (getTargetParser().getTargetOptions().MCNoWarn)
  980. return false;
  981. if (getTargetParser().getTargetOptions().MCFatalWarnings)
  982. return Error(L, Msg, Range);
  983. printMessage(L, SourceMgr::DK_Warning, Msg, Range);
  984. printMacroInstantiations();
  985. return false;
  986. }
  987. bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
  988. HadError = true;
  989. printMessage(L, SourceMgr::DK_Error, Msg, Range);
  990. printMacroInstantiations();
  991. return true;
  992. }
  993. bool MasmParser::enterIncludeFile(const std::string &Filename) {
  994. std::string IncludedFile;
  995. unsigned NewBuf =
  996. SrcMgr.AddIncludeFile(Filename, Lexer.getLoc(), IncludedFile);
  997. if (!NewBuf)
  998. return true;
  999. CurBuffer = NewBuf;
  1000. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
  1001. EndStatementAtEOFStack.push_back(true);
  1002. return false;
  1003. }
  1004. void MasmParser::jumpToLoc(SMLoc Loc, unsigned InBuffer,
  1005. bool EndStatementAtEOF) {
  1006. CurBuffer = InBuffer ? InBuffer : SrcMgr.FindBufferContainingLoc(Loc);
  1007. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(),
  1008. Loc.getPointer(), EndStatementAtEOF);
  1009. }
  1010. bool MasmParser::expandMacros() {
  1011. const AsmToken &Tok = getTok();
  1012. const std::string IDLower = Tok.getIdentifier().lower();
  1013. const llvm::MCAsmMacro *M = getContext().lookupMacro(IDLower);
  1014. if (M && M->IsFunction && peekTok().is(AsmToken::LParen)) {
  1015. // This is a macro function invocation; expand it in place.
  1016. const SMLoc MacroLoc = Tok.getLoc();
  1017. const StringRef MacroId = Tok.getIdentifier();
  1018. Lexer.Lex();
  1019. if (handleMacroInvocation(M, MacroLoc)) {
  1020. Lexer.UnLex(AsmToken(AsmToken::Error, MacroId));
  1021. Lexer.Lex();
  1022. }
  1023. return false;
  1024. }
  1025. std::optional<std::string> ExpandedValue;
  1026. auto BuiltinIt = BuiltinSymbolMap.find(IDLower);
  1027. if (BuiltinIt != BuiltinSymbolMap.end()) {
  1028. ExpandedValue =
  1029. evaluateBuiltinTextMacro(BuiltinIt->getValue(), Tok.getLoc());
  1030. } else {
  1031. auto VarIt = Variables.find(IDLower);
  1032. if (VarIt != Variables.end() && VarIt->getValue().IsText) {
  1033. ExpandedValue = VarIt->getValue().TextValue;
  1034. }
  1035. }
  1036. if (!ExpandedValue)
  1037. return true;
  1038. std::unique_ptr<MemoryBuffer> Instantiation =
  1039. MemoryBuffer::getMemBufferCopy(*ExpandedValue, "<instantiation>");
  1040. // Jump to the macro instantiation and prime the lexer.
  1041. CurBuffer =
  1042. SrcMgr.AddNewSourceBuffer(std::move(Instantiation), Tok.getEndLoc());
  1043. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
  1044. /*EndStatementAtEOF=*/false);
  1045. EndStatementAtEOFStack.push_back(false);
  1046. Lexer.Lex();
  1047. return false;
  1048. }
  1049. const AsmToken &MasmParser::Lex(ExpandKind ExpandNextToken) {
  1050. if (Lexer.getTok().is(AsmToken::Error))
  1051. Error(Lexer.getErrLoc(), Lexer.getErr());
  1052. // if it's a end of statement with a comment in it
  1053. if (getTok().is(AsmToken::EndOfStatement)) {
  1054. // if this is a line comment output it.
  1055. if (!getTok().getString().empty() && getTok().getString().front() != '\n' &&
  1056. getTok().getString().front() != '\r' && MAI.preserveAsmComments())
  1057. Out.addExplicitComment(Twine(getTok().getString()));
  1058. }
  1059. const AsmToken *tok = &Lexer.Lex();
  1060. bool StartOfStatement = Lexer.isAtStartOfStatement();
  1061. while (ExpandNextToken == ExpandMacros && tok->is(AsmToken::Identifier)) {
  1062. if (StartOfStatement) {
  1063. AsmToken NextTok;
  1064. MutableArrayRef<AsmToken> Buf(NextTok);
  1065. size_t ReadCount = Lexer.peekTokens(Buf);
  1066. if (ReadCount && NextTok.is(AsmToken::Identifier) &&
  1067. (NextTok.getString().equals_insensitive("equ") ||
  1068. NextTok.getString().equals_insensitive("textequ"))) {
  1069. // This looks like an EQU or TEXTEQU directive; don't expand the
  1070. // identifier, allowing for redefinitions.
  1071. break;
  1072. }
  1073. }
  1074. if (expandMacros())
  1075. break;
  1076. }
  1077. // Parse comments here to be deferred until end of next statement.
  1078. while (tok->is(AsmToken::Comment)) {
  1079. if (MAI.preserveAsmComments())
  1080. Out.addExplicitComment(Twine(tok->getString()));
  1081. tok = &Lexer.Lex();
  1082. }
  1083. // Recognize and bypass line continuations.
  1084. while (tok->is(AsmToken::BackSlash) &&
  1085. peekTok().is(AsmToken::EndOfStatement)) {
  1086. // Eat both the backslash and the end of statement.
  1087. Lexer.Lex();
  1088. tok = &Lexer.Lex();
  1089. }
  1090. if (tok->is(AsmToken::Eof)) {
  1091. // If this is the end of an included file, pop the parent file off the
  1092. // include stack.
  1093. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
  1094. if (ParentIncludeLoc != SMLoc()) {
  1095. EndStatementAtEOFStack.pop_back();
  1096. jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
  1097. return Lex();
  1098. }
  1099. EndStatementAtEOFStack.pop_back();
  1100. assert(EndStatementAtEOFStack.empty());
  1101. }
  1102. return *tok;
  1103. }
  1104. const AsmToken MasmParser::peekTok(bool ShouldSkipSpace) {
  1105. AsmToken Tok;
  1106. MutableArrayRef<AsmToken> Buf(Tok);
  1107. size_t ReadCount = Lexer.peekTokens(Buf, ShouldSkipSpace);
  1108. if (ReadCount == 0) {
  1109. // If this is the end of an included file, pop the parent file off the
  1110. // include stack.
  1111. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
  1112. if (ParentIncludeLoc != SMLoc()) {
  1113. EndStatementAtEOFStack.pop_back();
  1114. jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
  1115. return peekTok(ShouldSkipSpace);
  1116. }
  1117. EndStatementAtEOFStack.pop_back();
  1118. assert(EndStatementAtEOFStack.empty());
  1119. }
  1120. assert(ReadCount == 1);
  1121. return Tok;
  1122. }
  1123. bool MasmParser::enabledGenDwarfForAssembly() {
  1124. // Check whether the user specified -g.
  1125. if (!getContext().getGenDwarfForAssembly())
  1126. return false;
  1127. // If we haven't encountered any .file directives (which would imply that
  1128. // the assembler source was produced with debug info already) then emit one
  1129. // describing the assembler source file itself.
  1130. if (getContext().getGenDwarfFileNumber() == 0) {
  1131. // Use the first #line directive for this, if any. It's preprocessed, so
  1132. // there is no checksum, and of course no source directive.
  1133. if (!FirstCppHashFilename.empty())
  1134. getContext().setMCLineTableRootFile(
  1135. /*CUID=*/0, getContext().getCompilationDir(), FirstCppHashFilename,
  1136. /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
  1137. const MCDwarfFile &RootFile =
  1138. getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
  1139. getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
  1140. /*CUID=*/0, getContext().getCompilationDir(), RootFile.Name,
  1141. RootFile.Checksum, RootFile.Source));
  1142. }
  1143. return true;
  1144. }
  1145. bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
  1146. // Create the initial section, if requested.
  1147. if (!NoInitialTextSection)
  1148. Out.initSections(false, getTargetParser().getSTI());
  1149. // Prime the lexer.
  1150. Lex();
  1151. HadError = false;
  1152. AsmCond StartingCondState = TheCondState;
  1153. SmallVector<AsmRewrite, 4> AsmStrRewrites;
  1154. // If we are generating dwarf for assembly source files save the initial text
  1155. // section. (Don't use enabledGenDwarfForAssembly() here, as we aren't
  1156. // emitting any actual debug info yet and haven't had a chance to parse any
  1157. // embedded .file directives.)
  1158. if (getContext().getGenDwarfForAssembly()) {
  1159. MCSection *Sec = getStreamer().getCurrentSectionOnly();
  1160. if (!Sec->getBeginSymbol()) {
  1161. MCSymbol *SectionStartSym = getContext().createTempSymbol();
  1162. getStreamer().emitLabel(SectionStartSym);
  1163. Sec->setBeginSymbol(SectionStartSym);
  1164. }
  1165. bool InsertResult = getContext().addGenDwarfSection(Sec);
  1166. assert(InsertResult && ".text section should not have debug info yet");
  1167. (void)InsertResult;
  1168. }
  1169. getTargetParser().onBeginOfFile();
  1170. // While we have input, parse each statement.
  1171. while (Lexer.isNot(AsmToken::Eof) ||
  1172. SrcMgr.getParentIncludeLoc(CurBuffer) != SMLoc()) {
  1173. // Skip through the EOF at the end of an inclusion.
  1174. if (Lexer.is(AsmToken::Eof))
  1175. Lex();
  1176. ParseStatementInfo Info(&AsmStrRewrites);
  1177. bool Parsed = parseStatement(Info, nullptr);
  1178. // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
  1179. // for printing ErrMsg via Lex() only if no (presumably better) parser error
  1180. // exists.
  1181. if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
  1182. Lex();
  1183. }
  1184. // parseStatement returned true so may need to emit an error.
  1185. printPendingErrors();
  1186. // Skipping to the next line if needed.
  1187. if (Parsed && !getLexer().isAtStartOfStatement())
  1188. eatToEndOfStatement();
  1189. }
  1190. getTargetParser().onEndOfFile();
  1191. printPendingErrors();
  1192. // All errors should have been emitted.
  1193. assert(!hasPendingError() && "unexpected error from parseStatement");
  1194. getTargetParser().flushPendingInstructions(getStreamer());
  1195. if (TheCondState.TheCond != StartingCondState.TheCond ||
  1196. TheCondState.Ignore != StartingCondState.Ignore)
  1197. printError(getTok().getLoc(), "unmatched .ifs or .elses");
  1198. // Check to see there are no empty DwarfFile slots.
  1199. const auto &LineTables = getContext().getMCDwarfLineTables();
  1200. if (!LineTables.empty()) {
  1201. unsigned Index = 0;
  1202. for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
  1203. if (File.Name.empty() && Index != 0)
  1204. printError(getTok().getLoc(), "unassigned file number: " +
  1205. Twine(Index) +
  1206. " for .file directives");
  1207. ++Index;
  1208. }
  1209. }
  1210. // Check to see that all assembler local symbols were actually defined.
  1211. // Targets that don't do subsections via symbols may not want this, though,
  1212. // so conservatively exclude them. Only do this if we're finalizing, though,
  1213. // as otherwise we won't necessarilly have seen everything yet.
  1214. if (!NoFinalize) {
  1215. if (MAI.hasSubsectionsViaSymbols()) {
  1216. for (const auto &TableEntry : getContext().getSymbols()) {
  1217. MCSymbol *Sym = TableEntry.getValue();
  1218. // Variable symbols may not be marked as defined, so check those
  1219. // explicitly. If we know it's a variable, we have a definition for
  1220. // the purposes of this check.
  1221. if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
  1222. // FIXME: We would really like to refer back to where the symbol was
  1223. // first referenced for a source location. We need to add something
  1224. // to track that. Currently, we just point to the end of the file.
  1225. printError(getTok().getLoc(), "assembler local symbol '" +
  1226. Sym->getName() + "' not defined");
  1227. }
  1228. }
  1229. // Temporary symbols like the ones for directional jumps don't go in the
  1230. // symbol table. They also need to be diagnosed in all (final) cases.
  1231. for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) {
  1232. if (std::get<2>(LocSym)->isUndefined()) {
  1233. // Reset the state of any "# line file" directives we've seen to the
  1234. // context as it was at the diagnostic site.
  1235. CppHashInfo = std::get<1>(LocSym);
  1236. printError(std::get<0>(LocSym), "directional label undefined");
  1237. }
  1238. }
  1239. }
  1240. // Finalize the output stream if there are no errors and if the client wants
  1241. // us to.
  1242. if (!HadError && !NoFinalize)
  1243. Out.finish(Lexer.getLoc());
  1244. return HadError || getContext().hadError();
  1245. }
  1246. bool MasmParser::checkForValidSection() {
  1247. if (!ParsingMSInlineAsm && !getStreamer().getCurrentSectionOnly()) {
  1248. Out.initSections(false, getTargetParser().getSTI());
  1249. return Error(getTok().getLoc(),
  1250. "expected section directive before assembly directive");
  1251. }
  1252. return false;
  1253. }
  1254. /// Throw away the rest of the line for testing purposes.
  1255. void MasmParser::eatToEndOfStatement() {
  1256. while (Lexer.isNot(AsmToken::EndOfStatement)) {
  1257. if (Lexer.is(AsmToken::Eof)) {
  1258. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
  1259. if (ParentIncludeLoc == SMLoc()) {
  1260. break;
  1261. }
  1262. EndStatementAtEOFStack.pop_back();
  1263. jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
  1264. }
  1265. Lexer.Lex();
  1266. }
  1267. // Eat EOL.
  1268. if (Lexer.is(AsmToken::EndOfStatement))
  1269. Lexer.Lex();
  1270. }
  1271. SmallVector<StringRef, 1>
  1272. MasmParser::parseStringRefsTo(AsmToken::TokenKind EndTok) {
  1273. SmallVector<StringRef, 1> Refs;
  1274. const char *Start = getTok().getLoc().getPointer();
  1275. while (Lexer.isNot(EndTok)) {
  1276. if (Lexer.is(AsmToken::Eof)) {
  1277. SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
  1278. if (ParentIncludeLoc == SMLoc()) {
  1279. break;
  1280. }
  1281. Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
  1282. EndStatementAtEOFStack.pop_back();
  1283. jumpToLoc(ParentIncludeLoc, 0, EndStatementAtEOFStack.back());
  1284. Lexer.Lex();
  1285. Start = getTok().getLoc().getPointer();
  1286. } else {
  1287. Lexer.Lex();
  1288. }
  1289. }
  1290. Refs.emplace_back(Start, getTok().getLoc().getPointer() - Start);
  1291. return Refs;
  1292. }
  1293. std::string MasmParser::parseStringTo(AsmToken::TokenKind EndTok) {
  1294. SmallVector<StringRef, 1> Refs = parseStringRefsTo(EndTok);
  1295. std::string Str;
  1296. for (StringRef S : Refs) {
  1297. Str.append(S.str());
  1298. }
  1299. return Str;
  1300. }
  1301. StringRef MasmParser::parseStringToEndOfStatement() {
  1302. const char *Start = getTok().getLoc().getPointer();
  1303. while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.isNot(AsmToken::Eof))
  1304. Lexer.Lex();
  1305. const char *End = getTok().getLoc().getPointer();
  1306. return StringRef(Start, End - Start);
  1307. }
  1308. /// Parse a paren expression and return it.
  1309. /// NOTE: This assumes the leading '(' has already been consumed.
  1310. ///
  1311. /// parenexpr ::= expr)
  1312. ///
  1313. bool MasmParser::parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
  1314. if (parseExpression(Res))
  1315. return true;
  1316. EndLoc = Lexer.getTok().getEndLoc();
  1317. return parseRParen();
  1318. }
  1319. /// Parse a bracket expression and return it.
  1320. /// NOTE: This assumes the leading '[' has already been consumed.
  1321. ///
  1322. /// bracketexpr ::= expr]
  1323. ///
  1324. bool MasmParser::parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
  1325. if (parseExpression(Res))
  1326. return true;
  1327. EndLoc = getTok().getEndLoc();
  1328. if (parseToken(AsmToken::RBrac, "expected ']' in brackets expression"))
  1329. return true;
  1330. return false;
  1331. }
  1332. /// Parse a primary expression and return it.
  1333. /// primaryexpr ::= (parenexpr
  1334. /// primaryexpr ::= symbol
  1335. /// primaryexpr ::= number
  1336. /// primaryexpr ::= '.'
  1337. /// primaryexpr ::= ~,+,-,'not' primaryexpr
  1338. /// primaryexpr ::= string
  1339. /// (a string is interpreted as a 64-bit number in big-endian base-256)
  1340. bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
  1341. AsmTypeInfo *TypeInfo) {
  1342. SMLoc FirstTokenLoc = getLexer().getLoc();
  1343. AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
  1344. switch (FirstTokenKind) {
  1345. default:
  1346. return TokError("unknown token in expression");
  1347. // If we have an error assume that we've already handled it.
  1348. case AsmToken::Error:
  1349. return true;
  1350. case AsmToken::Exclaim:
  1351. Lex(); // Eat the operator.
  1352. if (parsePrimaryExpr(Res, EndLoc, nullptr))
  1353. return true;
  1354. Res = MCUnaryExpr::createLNot(Res, getContext(), FirstTokenLoc);
  1355. return false;
  1356. case AsmToken::Dollar:
  1357. case AsmToken::At:
  1358. case AsmToken::Identifier: {
  1359. StringRef Identifier;
  1360. if (parseIdentifier(Identifier)) {
  1361. // We may have failed but $ may be a valid token.
  1362. if (getTok().is(AsmToken::Dollar)) {
  1363. if (Lexer.getMAI().getDollarIsPC()) {
  1364. Lex();
  1365. // This is a '$' reference, which references the current PC. Emit a
  1366. // temporary label to the streamer and refer to it.
  1367. MCSymbol *Sym = Ctx.createTempSymbol();
  1368. Out.emitLabel(Sym);
  1369. Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None,
  1370. getContext());
  1371. EndLoc = FirstTokenLoc;
  1372. return false;
  1373. }
  1374. return Error(FirstTokenLoc, "invalid token in expression");
  1375. }
  1376. }
  1377. // Parse named bitwise negation.
  1378. if (Identifier.equals_insensitive("not")) {
  1379. if (parsePrimaryExpr(Res, EndLoc, nullptr))
  1380. return true;
  1381. Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
  1382. return false;
  1383. }
  1384. // Parse directional local label references.
  1385. if (Identifier.equals_insensitive("@b") ||
  1386. Identifier.equals_insensitive("@f")) {
  1387. bool Before = Identifier.equals_insensitive("@b");
  1388. MCSymbol *Sym = getContext().getDirectionalLocalSymbol(0, Before);
  1389. if (Before && Sym->isUndefined())
  1390. return Error(FirstTokenLoc, "Expected @@ label before @B reference");
  1391. Res = MCSymbolRefExpr::create(Sym, getContext());
  1392. return false;
  1393. }
  1394. // Parse symbol variant.
  1395. std::pair<StringRef, StringRef> Split;
  1396. if (!MAI.useParensForSymbolVariant()) {
  1397. if (FirstTokenKind == AsmToken::String) {
  1398. if (Lexer.is(AsmToken::At)) {
  1399. Lex(); // eat @
  1400. SMLoc AtLoc = getLexer().getLoc();
  1401. StringRef VName;
  1402. if (parseIdentifier(VName))
  1403. return Error(AtLoc, "expected symbol variant after '@'");
  1404. Split = std::make_pair(Identifier, VName);
  1405. }
  1406. } else {
  1407. Split = Identifier.split('@');
  1408. }
  1409. } else if (Lexer.is(AsmToken::LParen)) {
  1410. Lex(); // eat '('.
  1411. StringRef VName;
  1412. parseIdentifier(VName);
  1413. // eat ')'.
  1414. if (parseToken(AsmToken::RParen,
  1415. "unexpected token in variant, expected ')'"))
  1416. return true;
  1417. Split = std::make_pair(Identifier, VName);
  1418. }
  1419. EndLoc = SMLoc::getFromPointer(Identifier.end());
  1420. // This is a symbol reference.
  1421. StringRef SymbolName = Identifier;
  1422. if (SymbolName.empty())
  1423. return Error(getLexer().getLoc(), "expected a symbol reference");
  1424. MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
  1425. // Look up the symbol variant if used.
  1426. if (!Split.second.empty()) {
  1427. Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
  1428. if (Variant != MCSymbolRefExpr::VK_Invalid) {
  1429. SymbolName = Split.first;
  1430. } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
  1431. Variant = MCSymbolRefExpr::VK_None;
  1432. } else {
  1433. return Error(SMLoc::getFromPointer(Split.second.begin()),
  1434. "invalid variant '" + Split.second + "'");
  1435. }
  1436. }
  1437. // Find the field offset if used.
  1438. AsmFieldInfo Info;
  1439. Split = SymbolName.split('.');
  1440. if (Split.second.empty()) {
  1441. } else {
  1442. SymbolName = Split.first;
  1443. if (lookUpField(SymbolName, Split.second, Info)) {
  1444. std::pair<StringRef, StringRef> BaseMember = Split.second.split('.');
  1445. StringRef Base = BaseMember.first, Member = BaseMember.second;
  1446. lookUpField(Base, Member, Info);
  1447. } else if (Structs.count(SymbolName.lower())) {
  1448. // This is actually a reference to a field offset.
  1449. Res = MCConstantExpr::create(Info.Offset, getContext());
  1450. return false;
  1451. }
  1452. }
  1453. MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName);
  1454. if (!Sym) {
  1455. // If this is a built-in numeric value, treat it as a constant.
  1456. auto BuiltinIt = BuiltinSymbolMap.find(SymbolName.lower());
  1457. const BuiltinSymbol Symbol = (BuiltinIt == BuiltinSymbolMap.end())
  1458. ? BI_NO_SYMBOL
  1459. : BuiltinIt->getValue();
  1460. if (Symbol != BI_NO_SYMBOL) {
  1461. const MCExpr *Value = evaluateBuiltinValue(Symbol, FirstTokenLoc);
  1462. if (Value) {
  1463. Res = Value;
  1464. return false;
  1465. }
  1466. }
  1467. // Variables use case-insensitive symbol names; if this is a variable, we
  1468. // find the symbol using its canonical name.
  1469. auto VarIt = Variables.find(SymbolName.lower());
  1470. if (VarIt != Variables.end())
  1471. SymbolName = VarIt->second.Name;
  1472. Sym = getContext().getOrCreateSymbol(SymbolName);
  1473. }
  1474. // If this is an absolute variable reference, substitute it now to preserve
  1475. // semantics in the face of reassignment.
  1476. if (Sym->isVariable()) {
  1477. auto V = Sym->getVariableValue(/*SetUsed=*/false);
  1478. bool DoInline = isa<MCConstantExpr>(V) && !Variant;
  1479. if (auto TV = dyn_cast<MCTargetExpr>(V))
  1480. DoInline = TV->inlineAssignedExpr();
  1481. if (DoInline) {
  1482. if (Variant)
  1483. return Error(EndLoc, "unexpected modifier on variable reference");
  1484. Res = Sym->getVariableValue(/*SetUsed=*/false);
  1485. return false;
  1486. }
  1487. }
  1488. // Otherwise create a symbol ref.
  1489. const MCExpr *SymRef =
  1490. MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc);
  1491. if (Info.Offset) {
  1492. Res = MCBinaryExpr::create(
  1493. MCBinaryExpr::Add, SymRef,
  1494. MCConstantExpr::create(Info.Offset, getContext()), getContext());
  1495. } else {
  1496. Res = SymRef;
  1497. }
  1498. if (TypeInfo) {
  1499. if (Info.Type.Name.empty()) {
  1500. auto TypeIt = KnownType.find(Identifier.lower());
  1501. if (TypeIt != KnownType.end()) {
  1502. Info.Type = TypeIt->second;
  1503. }
  1504. }
  1505. *TypeInfo = Info.Type;
  1506. }
  1507. return false;
  1508. }
  1509. case AsmToken::BigNum:
  1510. return TokError("literal value out of range for directive");
  1511. case AsmToken::Integer: {
  1512. int64_t IntVal = getTok().getIntVal();
  1513. Res = MCConstantExpr::create(IntVal, getContext());
  1514. EndLoc = Lexer.getTok().getEndLoc();
  1515. Lex(); // Eat token.
  1516. return false;
  1517. }
  1518. case AsmToken::String: {
  1519. // MASM strings (used as constants) are interpreted as big-endian base-256.
  1520. SMLoc ValueLoc = getTok().getLoc();
  1521. std::string Value;
  1522. if (parseEscapedString(Value))
  1523. return true;
  1524. if (Value.size() > 8)
  1525. return Error(ValueLoc, "literal value out of range");
  1526. uint64_t IntValue = 0;
  1527. for (const unsigned char CharVal : Value)
  1528. IntValue = (IntValue << 8) | CharVal;
  1529. Res = MCConstantExpr::create(IntValue, getContext());
  1530. return false;
  1531. }
  1532. case AsmToken::Real: {
  1533. APFloat RealVal(APFloat::IEEEdouble(), getTok().getString());
  1534. uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
  1535. Res = MCConstantExpr::create(IntVal, getContext());
  1536. EndLoc = Lexer.getTok().getEndLoc();
  1537. Lex(); // Eat token.
  1538. return false;
  1539. }
  1540. case AsmToken::Dot: {
  1541. // This is a '.' reference, which references the current PC. Emit a
  1542. // temporary label to the streamer and refer to it.
  1543. MCSymbol *Sym = Ctx.createTempSymbol();
  1544. Out.emitLabel(Sym);
  1545. Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
  1546. EndLoc = Lexer.getTok().getEndLoc();
  1547. Lex(); // Eat identifier.
  1548. return false;
  1549. }
  1550. case AsmToken::LParen:
  1551. Lex(); // Eat the '('.
  1552. return parseParenExpr(Res, EndLoc);
  1553. case AsmToken::LBrac:
  1554. if (!PlatformParser->HasBracketExpressions())
  1555. return TokError("brackets expression not supported on this target");
  1556. Lex(); // Eat the '['.
  1557. return parseBracketExpr(Res, EndLoc);
  1558. case AsmToken::Minus:
  1559. Lex(); // Eat the operator.
  1560. if (parsePrimaryExpr(Res, EndLoc, nullptr))
  1561. return true;
  1562. Res = MCUnaryExpr::createMinus(Res, getContext(), FirstTokenLoc);
  1563. return false;
  1564. case AsmToken::Plus:
  1565. Lex(); // Eat the operator.
  1566. if (parsePrimaryExpr(Res, EndLoc, nullptr))
  1567. return true;
  1568. Res = MCUnaryExpr::createPlus(Res, getContext(), FirstTokenLoc);
  1569. return false;
  1570. case AsmToken::Tilde:
  1571. Lex(); // Eat the operator.
  1572. if (parsePrimaryExpr(Res, EndLoc, nullptr))
  1573. return true;
  1574. Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
  1575. return false;
  1576. // MIPS unary expression operators. The lexer won't generate these tokens if
  1577. // MCAsmInfo::HasMipsExpressions is false for the target.
  1578. case AsmToken::PercentCall16:
  1579. case AsmToken::PercentCall_Hi:
  1580. case AsmToken::PercentCall_Lo:
  1581. case AsmToken::PercentDtprel_Hi:
  1582. case AsmToken::PercentDtprel_Lo:
  1583. case AsmToken::PercentGot:
  1584. case AsmToken::PercentGot_Disp:
  1585. case AsmToken::PercentGot_Hi:
  1586. case AsmToken::PercentGot_Lo:
  1587. case AsmToken::PercentGot_Ofst:
  1588. case AsmToken::PercentGot_Page:
  1589. case AsmToken::PercentGottprel:
  1590. case AsmToken::PercentGp_Rel:
  1591. case AsmToken::PercentHi:
  1592. case AsmToken::PercentHigher:
  1593. case AsmToken::PercentHighest:
  1594. case AsmToken::PercentLo:
  1595. case AsmToken::PercentNeg:
  1596. case AsmToken::PercentPcrel_Hi:
  1597. case AsmToken::PercentPcrel_Lo:
  1598. case AsmToken::PercentTlsgd:
  1599. case AsmToken::PercentTlsldm:
  1600. case AsmToken::PercentTprel_Hi:
  1601. case AsmToken::PercentTprel_Lo:
  1602. Lex(); // Eat the operator.
  1603. if (Lexer.isNot(AsmToken::LParen))
  1604. return TokError("expected '(' after operator");
  1605. Lex(); // Eat the operator.
  1606. if (parseExpression(Res, EndLoc))
  1607. return true;
  1608. if (parseRParen())
  1609. return true;
  1610. Res = getTargetParser().createTargetUnaryExpr(Res, FirstTokenKind, Ctx);
  1611. return !Res;
  1612. }
  1613. }
  1614. bool MasmParser::parseExpression(const MCExpr *&Res) {
  1615. SMLoc EndLoc;
  1616. return parseExpression(Res, EndLoc);
  1617. }
  1618. /// This function checks if the next token is <string> type or arithmetic.
  1619. /// string that begin with character '<' must end with character '>'.
  1620. /// otherwise it is arithmetics.
  1621. /// If the function returns a 'true' value,
  1622. /// the End argument will be filled with the last location pointed to the '>'
  1623. /// character.
  1624. static bool isAngleBracketString(SMLoc &StrLoc, SMLoc &EndLoc) {
  1625. assert((StrLoc.getPointer() != nullptr) &&
  1626. "Argument to the function cannot be a NULL value");
  1627. const char *CharPtr = StrLoc.getPointer();
  1628. while ((*CharPtr != '>') && (*CharPtr != '\n') && (*CharPtr != '\r') &&
  1629. (*CharPtr != '\0')) {
  1630. if (*CharPtr == '!')
  1631. CharPtr++;
  1632. CharPtr++;
  1633. }
  1634. if (*CharPtr == '>') {
  1635. EndLoc = StrLoc.getFromPointer(CharPtr + 1);
  1636. return true;
  1637. }
  1638. return false;
  1639. }
  1640. /// creating a string without the escape characters '!'.
  1641. static std::string angleBracketString(StringRef BracketContents) {
  1642. std::string Res;
  1643. for (size_t Pos = 0; Pos < BracketContents.size(); Pos++) {
  1644. if (BracketContents[Pos] == '!')
  1645. Pos++;
  1646. Res += BracketContents[Pos];
  1647. }
  1648. return Res;
  1649. }
  1650. /// Parse an expression and return it.
  1651. ///
  1652. /// expr ::= expr &&,|| expr -> lowest.
  1653. /// expr ::= expr |,^,&,! expr
  1654. /// expr ::= expr ==,!=,<>,<,<=,>,>= expr
  1655. /// expr ::= expr <<,>> expr
  1656. /// expr ::= expr +,- expr
  1657. /// expr ::= expr *,/,% expr -> highest.
  1658. /// expr ::= primaryexpr
  1659. ///
  1660. bool MasmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
  1661. // Parse the expression.
  1662. Res = nullptr;
  1663. if (getTargetParser().parsePrimaryExpr(Res, EndLoc) ||
  1664. parseBinOpRHS(1, Res, EndLoc))
  1665. return true;
  1666. // Try to constant fold it up front, if possible. Do not exploit
  1667. // assembler here.
  1668. int64_t Value;
  1669. if (Res->evaluateAsAbsolute(Value))
  1670. Res = MCConstantExpr::create(Value, getContext());
  1671. return false;
  1672. }
  1673. bool MasmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
  1674. Res = nullptr;
  1675. return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc);
  1676. }
  1677. bool MasmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
  1678. SMLoc &EndLoc) {
  1679. if (parseParenExpr(Res, EndLoc))
  1680. return true;
  1681. for (; ParenDepth > 0; --ParenDepth) {
  1682. if (parseBinOpRHS(1, Res, EndLoc))
  1683. return true;
  1684. // We don't Lex() the last RParen.
  1685. // This is the same behavior as parseParenExpression().
  1686. if (ParenDepth - 1 > 0) {
  1687. EndLoc = getTok().getEndLoc();
  1688. if (parseRParen())
  1689. return true;
  1690. }
  1691. }
  1692. return false;
  1693. }
  1694. bool MasmParser::parseAbsoluteExpression(int64_t &Res) {
  1695. const MCExpr *Expr;
  1696. SMLoc StartLoc = Lexer.getLoc();
  1697. if (parseExpression(Expr))
  1698. return true;
  1699. if (!Expr->evaluateAsAbsolute(Res, getStreamer().getAssemblerPtr()))
  1700. return Error(StartLoc, "expected absolute expression");
  1701. return false;
  1702. }
  1703. static unsigned getGNUBinOpPrecedence(AsmToken::TokenKind K,
  1704. MCBinaryExpr::Opcode &Kind,
  1705. bool ShouldUseLogicalShr,
  1706. bool EndExpressionAtGreater) {
  1707. switch (K) {
  1708. default:
  1709. return 0; // not a binop.
  1710. // Lowest Precedence: &&, ||
  1711. case AsmToken::AmpAmp:
  1712. Kind = MCBinaryExpr::LAnd;
  1713. return 2;
  1714. case AsmToken::PipePipe:
  1715. Kind = MCBinaryExpr::LOr;
  1716. return 1;
  1717. // Low Precedence: ==, !=, <>, <, <=, >, >=
  1718. case AsmToken::EqualEqual:
  1719. Kind = MCBinaryExpr::EQ;
  1720. return 3;
  1721. case AsmToken::ExclaimEqual:
  1722. case AsmToken::LessGreater:
  1723. Kind = MCBinaryExpr::NE;
  1724. return 3;
  1725. case AsmToken::Less:
  1726. Kind = MCBinaryExpr::LT;
  1727. return 3;
  1728. case AsmToken::LessEqual:
  1729. Kind = MCBinaryExpr::LTE;
  1730. return 3;
  1731. case AsmToken::Greater:
  1732. if (EndExpressionAtGreater)
  1733. return 0;
  1734. Kind = MCBinaryExpr::GT;
  1735. return 3;
  1736. case AsmToken::GreaterEqual:
  1737. Kind = MCBinaryExpr::GTE;
  1738. return 3;
  1739. // Low Intermediate Precedence: +, -
  1740. case AsmToken::Plus:
  1741. Kind = MCBinaryExpr::Add;
  1742. return 4;
  1743. case AsmToken::Minus:
  1744. Kind = MCBinaryExpr::Sub;
  1745. return 4;
  1746. // High Intermediate Precedence: |, &, ^
  1747. case AsmToken::Pipe:
  1748. Kind = MCBinaryExpr::Or;
  1749. return 5;
  1750. case AsmToken::Caret:
  1751. Kind = MCBinaryExpr::Xor;
  1752. return 5;
  1753. case AsmToken::Amp:
  1754. Kind = MCBinaryExpr::And;
  1755. return 5;
  1756. // Highest Precedence: *, /, %, <<, >>
  1757. case AsmToken::Star:
  1758. Kind = MCBinaryExpr::Mul;
  1759. return 6;
  1760. case AsmToken::Slash:
  1761. Kind = MCBinaryExpr::Div;
  1762. return 6;
  1763. case AsmToken::Percent:
  1764. Kind = MCBinaryExpr::Mod;
  1765. return 6;
  1766. case AsmToken::LessLess:
  1767. Kind = MCBinaryExpr::Shl;
  1768. return 6;
  1769. case AsmToken::GreaterGreater:
  1770. if (EndExpressionAtGreater)
  1771. return 0;
  1772. Kind = ShouldUseLogicalShr ? MCBinaryExpr::LShr : MCBinaryExpr::AShr;
  1773. return 6;
  1774. }
  1775. }
  1776. unsigned MasmParser::getBinOpPrecedence(AsmToken::TokenKind K,
  1777. MCBinaryExpr::Opcode &Kind) {
  1778. bool ShouldUseLogicalShr = MAI.shouldUseLogicalShr();
  1779. return getGNUBinOpPrecedence(K, Kind, ShouldUseLogicalShr,
  1780. AngleBracketDepth > 0);
  1781. }
  1782. /// Parse all binary operators with precedence >= 'Precedence'.
  1783. /// Res contains the LHS of the expression on input.
  1784. bool MasmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
  1785. SMLoc &EndLoc) {
  1786. SMLoc StartLoc = Lexer.getLoc();
  1787. while (true) {
  1788. AsmToken::TokenKind TokKind = Lexer.getKind();
  1789. if (Lexer.getKind() == AsmToken::Identifier) {
  1790. TokKind = StringSwitch<AsmToken::TokenKind>(Lexer.getTok().getString())
  1791. .CaseLower("and", AsmToken::Amp)
  1792. .CaseLower("not", AsmToken::Exclaim)
  1793. .CaseLower("or", AsmToken::Pipe)
  1794. .CaseLower("xor", AsmToken::Caret)
  1795. .CaseLower("shl", AsmToken::LessLess)
  1796. .CaseLower("shr", AsmToken::GreaterGreater)
  1797. .CaseLower("eq", AsmToken::EqualEqual)
  1798. .CaseLower("ne", AsmToken::ExclaimEqual)
  1799. .CaseLower("lt", AsmToken::Less)
  1800. .CaseLower("le", AsmToken::LessEqual)
  1801. .CaseLower("gt", AsmToken::Greater)
  1802. .CaseLower("ge", AsmToken::GreaterEqual)
  1803. .Default(TokKind);
  1804. }
  1805. MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
  1806. unsigned TokPrec = getBinOpPrecedence(TokKind, Kind);
  1807. // If the next token is lower precedence than we are allowed to eat, return
  1808. // successfully with what we ate already.
  1809. if (TokPrec < Precedence)
  1810. return false;
  1811. Lex();
  1812. // Eat the next primary expression.
  1813. const MCExpr *RHS;
  1814. if (getTargetParser().parsePrimaryExpr(RHS, EndLoc))
  1815. return true;
  1816. // If BinOp binds less tightly with RHS than the operator after RHS, let
  1817. // the pending operator take RHS as its LHS.
  1818. MCBinaryExpr::Opcode Dummy;
  1819. unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
  1820. if (TokPrec < NextTokPrec && parseBinOpRHS(TokPrec + 1, RHS, EndLoc))
  1821. return true;
  1822. // Merge LHS and RHS according to operator.
  1823. Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc);
  1824. }
  1825. }
  1826. /// ParseStatement:
  1827. /// ::= % statement
  1828. /// ::= EndOfStatement
  1829. /// ::= Label* Directive ...Operands... EndOfStatement
  1830. /// ::= Label* Identifier OperandList* EndOfStatement
  1831. bool MasmParser::parseStatement(ParseStatementInfo &Info,
  1832. MCAsmParserSemaCallback *SI) {
  1833. assert(!hasPendingError() && "parseStatement started with pending error");
  1834. // Eat initial spaces and comments.
  1835. while (Lexer.is(AsmToken::Space))
  1836. Lex();
  1837. if (Lexer.is(AsmToken::EndOfStatement)) {
  1838. // If this is a line comment we can drop it safely.
  1839. if (getTok().getString().empty() || getTok().getString().front() == '\r' ||
  1840. getTok().getString().front() == '\n')
  1841. Out.addBlankLine();
  1842. Lex();
  1843. return false;
  1844. }
  1845. // If preceded by an expansion operator, first expand all text macros and
  1846. // macro functions.
  1847. if (getTok().is(AsmToken::Percent)) {
  1848. SMLoc ExpansionLoc = getTok().getLoc();
  1849. if (parseToken(AsmToken::Percent) || expandStatement(ExpansionLoc))
  1850. return true;
  1851. }
  1852. // Statements always start with an identifier, unless we're dealing with a
  1853. // processor directive (.386, .686, etc.) that lexes as a real.
  1854. AsmToken ID = getTok();
  1855. SMLoc IDLoc = ID.getLoc();
  1856. StringRef IDVal;
  1857. if (Lexer.is(AsmToken::HashDirective))
  1858. return parseCppHashLineFilenameComment(IDLoc);
  1859. if (Lexer.is(AsmToken::Dot)) {
  1860. // Treat '.' as a valid identifier in this context.
  1861. Lex();
  1862. IDVal = ".";
  1863. } else if (Lexer.is(AsmToken::LCurly)) {
  1864. // Treat '{' as a valid identifier in this context.
  1865. Lex();
  1866. IDVal = "{";
  1867. } else if (Lexer.is(AsmToken::RCurly)) {
  1868. // Treat '}' as a valid identifier in this context.
  1869. Lex();
  1870. IDVal = "}";
  1871. } else if (Lexer.is(AsmToken::Star) &&
  1872. getTargetParser().starIsStartOfStatement()) {
  1873. // Accept '*' as a valid start of statement.
  1874. Lex();
  1875. IDVal = "*";
  1876. } else if (Lexer.is(AsmToken::Real)) {
  1877. // Treat ".<number>" as a valid identifier in this context.
  1878. IDVal = getTok().getString();
  1879. Lex(); // always eat a token
  1880. if (!IDVal.startswith("."))
  1881. return Error(IDLoc, "unexpected token at start of statement");
  1882. } else if (parseIdentifier(IDVal, StartOfStatement)) {
  1883. if (!TheCondState.Ignore) {
  1884. Lex(); // always eat a token
  1885. return Error(IDLoc, "unexpected token at start of statement");
  1886. }
  1887. IDVal = "";
  1888. }
  1889. // Handle conditional assembly here before checking for skipping. We
  1890. // have to do this so that .endif isn't skipped in a ".if 0" block for
  1891. // example.
  1892. StringMap<DirectiveKind>::const_iterator DirKindIt =
  1893. DirectiveKindMap.find(IDVal.lower());
  1894. DirectiveKind DirKind = (DirKindIt == DirectiveKindMap.end())
  1895. ? DK_NO_DIRECTIVE
  1896. : DirKindIt->getValue();
  1897. switch (DirKind) {
  1898. default:
  1899. break;
  1900. case DK_IF:
  1901. case DK_IFE:
  1902. return parseDirectiveIf(IDLoc, DirKind);
  1903. case DK_IFB:
  1904. return parseDirectiveIfb(IDLoc, true);
  1905. case DK_IFNB:
  1906. return parseDirectiveIfb(IDLoc, false);
  1907. case DK_IFDEF:
  1908. return parseDirectiveIfdef(IDLoc, true);
  1909. case DK_IFNDEF:
  1910. return parseDirectiveIfdef(IDLoc, false);
  1911. case DK_IFDIF:
  1912. return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
  1913. /*CaseInsensitive=*/false);
  1914. case DK_IFDIFI:
  1915. return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/false,
  1916. /*CaseInsensitive=*/true);
  1917. case DK_IFIDN:
  1918. return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
  1919. /*CaseInsensitive=*/false);
  1920. case DK_IFIDNI:
  1921. return parseDirectiveIfidn(IDLoc, /*ExpectEqual=*/true,
  1922. /*CaseInsensitive=*/true);
  1923. case DK_ELSEIF:
  1924. case DK_ELSEIFE:
  1925. return parseDirectiveElseIf(IDLoc, DirKind);
  1926. case DK_ELSEIFB:
  1927. return parseDirectiveElseIfb(IDLoc, true);
  1928. case DK_ELSEIFNB:
  1929. return parseDirectiveElseIfb(IDLoc, false);
  1930. case DK_ELSEIFDEF:
  1931. return parseDirectiveElseIfdef(IDLoc, true);
  1932. case DK_ELSEIFNDEF:
  1933. return parseDirectiveElseIfdef(IDLoc, false);
  1934. case DK_ELSEIFDIF:
  1935. return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
  1936. /*CaseInsensitive=*/false);
  1937. case DK_ELSEIFDIFI:
  1938. return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/false,
  1939. /*CaseInsensitive=*/true);
  1940. case DK_ELSEIFIDN:
  1941. return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
  1942. /*CaseInsensitive=*/false);
  1943. case DK_ELSEIFIDNI:
  1944. return parseDirectiveElseIfidn(IDLoc, /*ExpectEqual=*/true,
  1945. /*CaseInsensitive=*/true);
  1946. case DK_ELSE:
  1947. return parseDirectiveElse(IDLoc);
  1948. case DK_ENDIF:
  1949. return parseDirectiveEndIf(IDLoc);
  1950. }
  1951. // Ignore the statement if in the middle of inactive conditional
  1952. // (e.g. ".if 0").
  1953. if (TheCondState.Ignore) {
  1954. eatToEndOfStatement();
  1955. return false;
  1956. }
  1957. // FIXME: Recurse on local labels?
  1958. // Check for a label.
  1959. // ::= identifier ':'
  1960. // ::= number ':'
  1961. if (Lexer.is(AsmToken::Colon) && getTargetParser().isLabel(ID)) {
  1962. if (checkForValidSection())
  1963. return true;
  1964. // identifier ':' -> Label.
  1965. Lex();
  1966. // Diagnose attempt to use '.' as a label.
  1967. if (IDVal == ".")
  1968. return Error(IDLoc, "invalid use of pseudo-symbol '.' as a label");
  1969. // Diagnose attempt to use a variable as a label.
  1970. //
  1971. // FIXME: Diagnostics. Note the location of the definition as a label.
  1972. // FIXME: This doesn't diagnose assignment to a symbol which has been
  1973. // implicitly marked as external.
  1974. MCSymbol *Sym;
  1975. if (ParsingMSInlineAsm && SI) {
  1976. StringRef RewrittenLabel =
  1977. SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
  1978. assert(!RewrittenLabel.empty() &&
  1979. "We should have an internal name here.");
  1980. Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
  1981. RewrittenLabel);
  1982. IDVal = RewrittenLabel;
  1983. }
  1984. // Handle directional local labels
  1985. if (IDVal == "@@") {
  1986. Sym = Ctx.createDirectionalLocalSymbol(0);
  1987. } else {
  1988. Sym = getContext().getOrCreateSymbol(IDVal);
  1989. }
  1990. // End of Labels should be treated as end of line for lexing
  1991. // purposes but that information is not available to the Lexer who
  1992. // does not understand Labels. This may cause us to see a Hash
  1993. // here instead of a preprocessor line comment.
  1994. if (getTok().is(AsmToken::Hash)) {
  1995. std::string CommentStr = parseStringTo(AsmToken::EndOfStatement);
  1996. Lexer.Lex();
  1997. Lexer.UnLex(AsmToken(AsmToken::EndOfStatement, CommentStr));
  1998. }
  1999. // Consume any end of statement token, if present, to avoid spurious
  2000. // addBlankLine calls().
  2001. if (getTok().is(AsmToken::EndOfStatement)) {
  2002. Lex();
  2003. }
  2004. getTargetParser().doBeforeLabelEmit(Sym, IDLoc);
  2005. // Emit the label.
  2006. if (!getTargetParser().isParsingMSInlineAsm())
  2007. Out.emitLabel(Sym, IDLoc);
  2008. // If we are generating dwarf for assembly source files then gather the
  2009. // info to make a dwarf label entry for this label if needed.
  2010. if (enabledGenDwarfForAssembly())
  2011. MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(),
  2012. IDLoc);
  2013. getTargetParser().onLabelParsed(Sym);
  2014. return false;
  2015. }
  2016. // If macros are enabled, check to see if this is a macro instantiation.
  2017. if (const MCAsmMacro *M = getContext().lookupMacro(IDVal.lower())) {
  2018. return handleMacroEntry(M, IDLoc);
  2019. }
  2020. // Otherwise, we have a normal instruction or directive.
  2021. if (DirKind != DK_NO_DIRECTIVE) {
  2022. // There are several entities interested in parsing directives:
  2023. //
  2024. // 1. Asm parser extensions. For example, platform-specific parsers
  2025. // (like the ELF parser) register themselves as extensions.
  2026. // 2. The target-specific assembly parser. Some directives are target
  2027. // specific or may potentially behave differently on certain targets.
  2028. // 3. The generic directive parser implemented by this class. These are
  2029. // all the directives that behave in a target and platform independent
  2030. // manner, or at least have a default behavior that's shared between
  2031. // all targets and platforms.
  2032. getTargetParser().flushPendingInstructions(getStreamer());
  2033. // Special-case handling of structure-end directives at higher priority,
  2034. // since ENDS is overloaded as a segment-end directive.
  2035. if (IDVal.equals_insensitive("ends") && StructInProgress.size() > 1 &&
  2036. getTok().is(AsmToken::EndOfStatement)) {
  2037. return parseDirectiveNestedEnds();
  2038. }
  2039. // First, check the extension directive map to see if any extension has
  2040. // registered itself to parse this directive.
  2041. std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
  2042. ExtensionDirectiveMap.lookup(IDVal.lower());
  2043. if (Handler.first)
  2044. return (*Handler.second)(Handler.first, IDVal, IDLoc);
  2045. // Next, let the target-specific assembly parser try.
  2046. SMLoc StartTokLoc = getTok().getLoc();
  2047. bool TPDirectiveReturn =
  2048. ID.is(AsmToken::Identifier) && getTargetParser().ParseDirective(ID);
  2049. if (hasPendingError())
  2050. return true;
  2051. // Currently the return value should be true if we are
  2052. // uninterested but as this is at odds with the standard parsing
  2053. // convention (return true = error) we have instances of a parsed
  2054. // directive that fails returning true as an error. Catch these
  2055. // cases as best as possible errors here.
  2056. if (TPDirectiveReturn && StartTokLoc != getTok().getLoc())
  2057. return true;
  2058. // Return if we did some parsing or believe we succeeded.
  2059. if (!TPDirectiveReturn || StartTokLoc != getTok().getLoc())
  2060. return false;
  2061. // Finally, if no one else is interested in this directive, it must be
  2062. // generic and familiar to this class.
  2063. switch (DirKind) {
  2064. default:
  2065. break;
  2066. case DK_ASCII:
  2067. return parseDirectiveAscii(IDVal, false);
  2068. case DK_ASCIZ:
  2069. case DK_STRING:
  2070. return parseDirectiveAscii(IDVal, true);
  2071. case DK_BYTE:
  2072. case DK_SBYTE:
  2073. case DK_DB:
  2074. return parseDirectiveValue(IDVal, 1);
  2075. case DK_WORD:
  2076. case DK_SWORD:
  2077. case DK_DW:
  2078. return parseDirectiveValue(IDVal, 2);
  2079. case DK_DWORD:
  2080. case DK_SDWORD:
  2081. case DK_DD:
  2082. return parseDirectiveValue(IDVal, 4);
  2083. case DK_FWORD:
  2084. case DK_DF:
  2085. return parseDirectiveValue(IDVal, 6);
  2086. case DK_QWORD:
  2087. case DK_SQWORD:
  2088. case DK_DQ:
  2089. return parseDirectiveValue(IDVal, 8);
  2090. case DK_REAL4:
  2091. return parseDirectiveRealValue(IDVal, APFloat::IEEEsingle(), 4);
  2092. case DK_REAL8:
  2093. return parseDirectiveRealValue(IDVal, APFloat::IEEEdouble(), 8);
  2094. case DK_REAL10:
  2095. return parseDirectiveRealValue(IDVal, APFloat::x87DoubleExtended(), 10);
  2096. case DK_STRUCT:
  2097. case DK_UNION:
  2098. return parseDirectiveNestedStruct(IDVal, DirKind);
  2099. case DK_ENDS:
  2100. return parseDirectiveNestedEnds();
  2101. case DK_ALIGN:
  2102. return parseDirectiveAlign();
  2103. case DK_EVEN:
  2104. return parseDirectiveEven();
  2105. case DK_ORG:
  2106. return parseDirectiveOrg();
  2107. case DK_EXTERN:
  2108. return parseDirectiveExtern();
  2109. case DK_PUBLIC:
  2110. return parseDirectiveSymbolAttribute(MCSA_Global);
  2111. case DK_COMM:
  2112. return parseDirectiveComm(/*IsLocal=*/false);
  2113. case DK_COMMENT:
  2114. return parseDirectiveComment(IDLoc);
  2115. case DK_INCLUDE:
  2116. return parseDirectiveInclude();
  2117. case DK_REPEAT:
  2118. return parseDirectiveRepeat(IDLoc, IDVal);
  2119. case DK_WHILE:
  2120. return parseDirectiveWhile(IDLoc);
  2121. case DK_FOR:
  2122. return parseDirectiveFor(IDLoc, IDVal);
  2123. case DK_FORC:
  2124. return parseDirectiveForc(IDLoc, IDVal);
  2125. case DK_FILE:
  2126. return parseDirectiveFile(IDLoc);
  2127. case DK_LINE:
  2128. return parseDirectiveLine();
  2129. case DK_LOC:
  2130. return parseDirectiveLoc();
  2131. case DK_STABS:
  2132. return parseDirectiveStabs();
  2133. case DK_CV_FILE:
  2134. return parseDirectiveCVFile();
  2135. case DK_CV_FUNC_ID:
  2136. return parseDirectiveCVFuncId();
  2137. case DK_CV_INLINE_SITE_ID:
  2138. return parseDirectiveCVInlineSiteId();
  2139. case DK_CV_LOC:
  2140. return parseDirectiveCVLoc();
  2141. case DK_CV_LINETABLE:
  2142. return parseDirectiveCVLinetable();
  2143. case DK_CV_INLINE_LINETABLE:
  2144. return parseDirectiveCVInlineLinetable();
  2145. case DK_CV_DEF_RANGE:
  2146. return parseDirectiveCVDefRange();
  2147. case DK_CV_STRING:
  2148. return parseDirectiveCVString();
  2149. case DK_CV_STRINGTABLE:
  2150. return parseDirectiveCVStringTable();
  2151. case DK_CV_FILECHECKSUMS:
  2152. return parseDirectiveCVFileChecksums();
  2153. case DK_CV_FILECHECKSUM_OFFSET:
  2154. return parseDirectiveCVFileChecksumOffset();
  2155. case DK_CV_FPO_DATA:
  2156. return parseDirectiveCVFPOData();
  2157. case DK_CFI_SECTIONS:
  2158. return parseDirectiveCFISections();
  2159. case DK_CFI_STARTPROC:
  2160. return parseDirectiveCFIStartProc();
  2161. case DK_CFI_ENDPROC:
  2162. return parseDirectiveCFIEndProc();
  2163. case DK_CFI_DEF_CFA:
  2164. return parseDirectiveCFIDefCfa(IDLoc);
  2165. case DK_CFI_DEF_CFA_OFFSET:
  2166. return parseDirectiveCFIDefCfaOffset();
  2167. case DK_CFI_ADJUST_CFA_OFFSET:
  2168. return parseDirectiveCFIAdjustCfaOffset();
  2169. case DK_CFI_DEF_CFA_REGISTER:
  2170. return parseDirectiveCFIDefCfaRegister(IDLoc);
  2171. case DK_CFI_OFFSET:
  2172. return parseDirectiveCFIOffset(IDLoc);
  2173. case DK_CFI_REL_OFFSET:
  2174. return parseDirectiveCFIRelOffset(IDLoc);
  2175. case DK_CFI_PERSONALITY:
  2176. return parseDirectiveCFIPersonalityOrLsda(true);
  2177. case DK_CFI_LSDA:
  2178. return parseDirectiveCFIPersonalityOrLsda(false);
  2179. case DK_CFI_REMEMBER_STATE:
  2180. return parseDirectiveCFIRememberState();
  2181. case DK_CFI_RESTORE_STATE:
  2182. return parseDirectiveCFIRestoreState();
  2183. case DK_CFI_SAME_VALUE:
  2184. return parseDirectiveCFISameValue(IDLoc);
  2185. case DK_CFI_RESTORE:
  2186. return parseDirectiveCFIRestore(IDLoc);
  2187. case DK_CFI_ESCAPE:
  2188. return parseDirectiveCFIEscape();
  2189. case DK_CFI_RETURN_COLUMN:
  2190. return parseDirectiveCFIReturnColumn(IDLoc);
  2191. case DK_CFI_SIGNAL_FRAME:
  2192. return parseDirectiveCFISignalFrame();
  2193. case DK_CFI_UNDEFINED:
  2194. return parseDirectiveCFIUndefined(IDLoc);
  2195. case DK_CFI_REGISTER:
  2196. return parseDirectiveCFIRegister(IDLoc);
  2197. case DK_CFI_WINDOW_SAVE:
  2198. return parseDirectiveCFIWindowSave();
  2199. case DK_EXITM:
  2200. Info.ExitValue = "";
  2201. return parseDirectiveExitMacro(IDLoc, IDVal, *Info.ExitValue);
  2202. case DK_ENDM:
  2203. Info.ExitValue = "";
  2204. return parseDirectiveEndMacro(IDVal);
  2205. case DK_PURGE:
  2206. return parseDirectivePurgeMacro(IDLoc);
  2207. case DK_END:
  2208. return parseDirectiveEnd(IDLoc);
  2209. case DK_ERR:
  2210. return parseDirectiveError(IDLoc);
  2211. case DK_ERRB:
  2212. return parseDirectiveErrorIfb(IDLoc, true);
  2213. case DK_ERRNB:
  2214. return parseDirectiveErrorIfb(IDLoc, false);
  2215. case DK_ERRDEF:
  2216. return parseDirectiveErrorIfdef(IDLoc, true);
  2217. case DK_ERRNDEF:
  2218. return parseDirectiveErrorIfdef(IDLoc, false);
  2219. case DK_ERRDIF:
  2220. return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
  2221. /*CaseInsensitive=*/false);
  2222. case DK_ERRDIFI:
  2223. return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/false,
  2224. /*CaseInsensitive=*/true);
  2225. case DK_ERRIDN:
  2226. return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
  2227. /*CaseInsensitive=*/false);
  2228. case DK_ERRIDNI:
  2229. return parseDirectiveErrorIfidn(IDLoc, /*ExpectEqual=*/true,
  2230. /*CaseInsensitive=*/true);
  2231. case DK_ERRE:
  2232. return parseDirectiveErrorIfe(IDLoc, true);
  2233. case DK_ERRNZ:
  2234. return parseDirectiveErrorIfe(IDLoc, false);
  2235. case DK_RADIX:
  2236. return parseDirectiveRadix(IDLoc);
  2237. case DK_ECHO:
  2238. return parseDirectiveEcho(IDLoc);
  2239. }
  2240. return Error(IDLoc, "unknown directive");
  2241. }
  2242. // We also check if this is allocating memory with user-defined type.
  2243. auto IDIt = Structs.find(IDVal.lower());
  2244. if (IDIt != Structs.end())
  2245. return parseDirectiveStructValue(/*Structure=*/IDIt->getValue(), IDVal,
  2246. IDLoc);
  2247. // Non-conditional Microsoft directives sometimes follow their first argument.
  2248. const AsmToken nextTok = getTok();
  2249. const StringRef nextVal = nextTok.getString();
  2250. const SMLoc nextLoc = nextTok.getLoc();
  2251. const AsmToken afterNextTok = peekTok();
  2252. // There are several entities interested in parsing infix directives:
  2253. //
  2254. // 1. Asm parser extensions. For example, platform-specific parsers
  2255. // (like the ELF parser) register themselves as extensions.
  2256. // 2. The generic directive parser implemented by this class. These are
  2257. // all the directives that behave in a target and platform independent
  2258. // manner, or at least have a default behavior that's shared between
  2259. // all targets and platforms.
  2260. getTargetParser().flushPendingInstructions(getStreamer());
  2261. // Special-case handling of structure-end directives at higher priority, since
  2262. // ENDS is overloaded as a segment-end directive.
  2263. if (nextVal.equals_insensitive("ends") && StructInProgress.size() == 1) {
  2264. Lex();
  2265. return parseDirectiveEnds(IDVal, IDLoc);
  2266. }
  2267. // First, check the extension directive map to see if any extension has
  2268. // registered itself to parse this directive.
  2269. std::pair<MCAsmParserExtension *, DirectiveHandler> Handler =
  2270. ExtensionDirectiveMap.lookup(nextVal.lower());
  2271. if (Handler.first) {
  2272. Lex();
  2273. Lexer.UnLex(ID);
  2274. return (*Handler.second)(Handler.first, nextVal, nextLoc);
  2275. }
  2276. // If no one else is interested in this directive, it must be
  2277. // generic and familiar to this class.
  2278. DirKindIt = DirectiveKindMap.find(nextVal.lower());
  2279. DirKind = (DirKindIt == DirectiveKindMap.end())
  2280. ? DK_NO_DIRECTIVE
  2281. : DirKindIt->getValue();
  2282. switch (DirKind) {
  2283. default:
  2284. break;
  2285. case DK_ASSIGN:
  2286. case DK_EQU:
  2287. case DK_TEXTEQU:
  2288. Lex();
  2289. return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc);
  2290. case DK_BYTE:
  2291. if (afterNextTok.is(AsmToken::Identifier) &&
  2292. afterNextTok.getString().equals_insensitive("ptr")) {
  2293. // Size directive; part of an instruction.
  2294. break;
  2295. }
  2296. [[fallthrough]];
  2297. case DK_SBYTE:
  2298. case DK_DB:
  2299. Lex();
  2300. return parseDirectiveNamedValue(nextVal, 1, IDVal, IDLoc);
  2301. case DK_WORD:
  2302. if (afterNextTok.is(AsmToken::Identifier) &&
  2303. afterNextTok.getString().equals_insensitive("ptr")) {
  2304. // Size directive; part of an instruction.
  2305. break;
  2306. }
  2307. [[fallthrough]];
  2308. case DK_SWORD:
  2309. case DK_DW:
  2310. Lex();
  2311. return parseDirectiveNamedValue(nextVal, 2, IDVal, IDLoc);
  2312. case DK_DWORD:
  2313. if (afterNextTok.is(AsmToken::Identifier) &&
  2314. afterNextTok.getString().equals_insensitive("ptr")) {
  2315. // Size directive; part of an instruction.
  2316. break;
  2317. }
  2318. [[fallthrough]];
  2319. case DK_SDWORD:
  2320. case DK_DD:
  2321. Lex();
  2322. return parseDirectiveNamedValue(nextVal, 4, IDVal, IDLoc);
  2323. case DK_FWORD:
  2324. if (afterNextTok.is(AsmToken::Identifier) &&
  2325. afterNextTok.getString().equals_insensitive("ptr")) {
  2326. // Size directive; part of an instruction.
  2327. break;
  2328. }
  2329. [[fallthrough]];
  2330. case DK_DF:
  2331. Lex();
  2332. return parseDirectiveNamedValue(nextVal, 6, IDVal, IDLoc);
  2333. case DK_QWORD:
  2334. if (afterNextTok.is(AsmToken::Identifier) &&
  2335. afterNextTok.getString().equals_insensitive("ptr")) {
  2336. // Size directive; part of an instruction.
  2337. break;
  2338. }
  2339. [[fallthrough]];
  2340. case DK_SQWORD:
  2341. case DK_DQ:
  2342. Lex();
  2343. return parseDirectiveNamedValue(nextVal, 8, IDVal, IDLoc);
  2344. case DK_REAL4:
  2345. Lex();
  2346. return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEsingle(), 4,
  2347. IDVal, IDLoc);
  2348. case DK_REAL8:
  2349. Lex();
  2350. return parseDirectiveNamedRealValue(nextVal, APFloat::IEEEdouble(), 8,
  2351. IDVal, IDLoc);
  2352. case DK_REAL10:
  2353. Lex();
  2354. return parseDirectiveNamedRealValue(nextVal, APFloat::x87DoubleExtended(),
  2355. 10, IDVal, IDLoc);
  2356. case DK_STRUCT:
  2357. case DK_UNION:
  2358. Lex();
  2359. return parseDirectiveStruct(nextVal, DirKind, IDVal, IDLoc);
  2360. case DK_ENDS:
  2361. Lex();
  2362. return parseDirectiveEnds(IDVal, IDLoc);
  2363. case DK_MACRO:
  2364. Lex();
  2365. return parseDirectiveMacro(IDVal, IDLoc);
  2366. }
  2367. // Finally, we check if this is allocating a variable with user-defined type.
  2368. auto NextIt = Structs.find(nextVal.lower());
  2369. if (NextIt != Structs.end()) {
  2370. Lex();
  2371. return parseDirectiveNamedStructValue(/*Structure=*/NextIt->getValue(),
  2372. nextVal, nextLoc, IDVal);
  2373. }
  2374. // __asm _emit or __asm __emit
  2375. if (ParsingMSInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
  2376. IDVal == "_EMIT" || IDVal == "__EMIT"))
  2377. return parseDirectiveMSEmit(IDLoc, Info, IDVal.size());
  2378. // __asm align
  2379. if (ParsingMSInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
  2380. return parseDirectiveMSAlign(IDLoc, Info);
  2381. if (ParsingMSInlineAsm && (IDVal == "even" || IDVal == "EVEN"))
  2382. Info.AsmRewrites->emplace_back(AOK_EVEN, IDLoc, 4);
  2383. if (checkForValidSection())
  2384. return true;
  2385. // Canonicalize the opcode to lower case.
  2386. std::string OpcodeStr = IDVal.lower();
  2387. ParseInstructionInfo IInfo(Info.AsmRewrites);
  2388. bool ParseHadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr, ID,
  2389. Info.ParsedOperands);
  2390. Info.ParseError = ParseHadError;
  2391. // Dump the parsed representation, if requested.
  2392. if (getShowParsedOperands()) {
  2393. SmallString<256> Str;
  2394. raw_svector_ostream OS(Str);
  2395. OS << "parsed instruction: [";
  2396. for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) {
  2397. if (i != 0)
  2398. OS << ", ";
  2399. Info.ParsedOperands[i]->print(OS);
  2400. }
  2401. OS << "]";
  2402. printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
  2403. }
  2404. // Fail even if ParseInstruction erroneously returns false.
  2405. if (hasPendingError() || ParseHadError)
  2406. return true;
  2407. // If we are generating dwarf for the current section then generate a .loc
  2408. // directive for the instruction.
  2409. if (!ParseHadError && enabledGenDwarfForAssembly() &&
  2410. getContext().getGenDwarfSectionSyms().count(
  2411. getStreamer().getCurrentSectionOnly())) {
  2412. unsigned Line;
  2413. if (ActiveMacros.empty())
  2414. Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
  2415. else
  2416. Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
  2417. ActiveMacros.front()->ExitBuffer);
  2418. // If we previously parsed a cpp hash file line comment then make sure the
  2419. // current Dwarf File is for the CppHashFilename if not then emit the
  2420. // Dwarf File table for it and adjust the line number for the .loc.
  2421. if (!CppHashInfo.Filename.empty()) {
  2422. unsigned FileNumber = getStreamer().emitDwarfFileDirective(
  2423. 0, StringRef(), CppHashInfo.Filename);
  2424. getContext().setGenDwarfFileNumber(FileNumber);
  2425. unsigned CppHashLocLineNo =
  2426. SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf);
  2427. Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo);
  2428. }
  2429. getStreamer().emitDwarfLocDirective(
  2430. getContext().getGenDwarfFileNumber(), Line, 0,
  2431. DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0,
  2432. StringRef());
  2433. }
  2434. // If parsing succeeded, match the instruction.
  2435. if (!ParseHadError) {
  2436. uint64_t ErrorInfo;
  2437. if (getTargetParser().MatchAndEmitInstruction(
  2438. IDLoc, Info.Opcode, Info.ParsedOperands, Out, ErrorInfo,
  2439. getTargetParser().isParsingMSInlineAsm()))
  2440. return true;
  2441. }
  2442. return false;
  2443. }
  2444. // Parse and erase curly braces marking block start/end.
  2445. bool MasmParser::parseCurlyBlockScope(
  2446. SmallVectorImpl<AsmRewrite> &AsmStrRewrites) {
  2447. // Identify curly brace marking block start/end.
  2448. if (Lexer.isNot(AsmToken::LCurly) && Lexer.isNot(AsmToken::RCurly))
  2449. return false;
  2450. SMLoc StartLoc = Lexer.getLoc();
  2451. Lex(); // Eat the brace.
  2452. if (Lexer.is(AsmToken::EndOfStatement))
  2453. Lex(); // Eat EndOfStatement following the brace.
  2454. // Erase the block start/end brace from the output asm string.
  2455. AsmStrRewrites.emplace_back(AOK_Skip, StartLoc, Lexer.getLoc().getPointer() -
  2456. StartLoc.getPointer());
  2457. return true;
  2458. }
  2459. /// parseCppHashLineFilenameComment as this:
  2460. /// ::= # number "filename"
  2461. bool MasmParser::parseCppHashLineFilenameComment(SMLoc L) {
  2462. Lex(); // Eat the hash token.
  2463. // Lexer only ever emits HashDirective if it fully formed if it's
  2464. // done the checking already so this is an internal error.
  2465. assert(getTok().is(AsmToken::Integer) &&
  2466. "Lexing Cpp line comment: Expected Integer");
  2467. int64_t LineNumber = getTok().getIntVal();
  2468. Lex();
  2469. assert(getTok().is(AsmToken::String) &&
  2470. "Lexing Cpp line comment: Expected String");
  2471. StringRef Filename = getTok().getString();
  2472. Lex();
  2473. // Get rid of the enclosing quotes.
  2474. Filename = Filename.substr(1, Filename.size() - 2);
  2475. // Save the SMLoc, Filename and LineNumber for later use by diagnostics
  2476. // and possibly DWARF file info.
  2477. CppHashInfo.Loc = L;
  2478. CppHashInfo.Filename = Filename;
  2479. CppHashInfo.LineNumber = LineNumber;
  2480. CppHashInfo.Buf = CurBuffer;
  2481. if (FirstCppHashFilename.empty())
  2482. FirstCppHashFilename = Filename;
  2483. return false;
  2484. }
  2485. /// will use the last parsed cpp hash line filename comment
  2486. /// for the Filename and LineNo if any in the diagnostic.
  2487. void MasmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
  2488. const MasmParser *Parser = static_cast<const MasmParser *>(Context);
  2489. raw_ostream &OS = errs();
  2490. const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
  2491. SMLoc DiagLoc = Diag.getLoc();
  2492. unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
  2493. unsigned CppHashBuf =
  2494. Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc);
  2495. // Like SourceMgr::printMessage() we need to print the include stack if any
  2496. // before printing the message.
  2497. unsigned DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
  2498. if (!Parser->SavedDiagHandler && DiagCurBuffer &&
  2499. DiagCurBuffer != DiagSrcMgr.getMainFileID()) {
  2500. SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
  2501. DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
  2502. }
  2503. // If we have not parsed a cpp hash line filename comment or the source
  2504. // manager changed or buffer changed (like in a nested include) then just
  2505. // print the normal diagnostic using its Filename and LineNo.
  2506. if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
  2507. DiagBuf != CppHashBuf) {
  2508. if (Parser->SavedDiagHandler)
  2509. Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
  2510. else
  2511. Diag.print(nullptr, OS);
  2512. return;
  2513. }
  2514. // Use the CppHashFilename and calculate a line number based on the
  2515. // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc
  2516. // for the diagnostic.
  2517. const std::string &Filename = std::string(Parser->CppHashInfo.Filename);
  2518. int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
  2519. int CppHashLocLineNo =
  2520. Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf);
  2521. int LineNo =
  2522. Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo);
  2523. SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo,
  2524. Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
  2525. Diag.getLineContents(), Diag.getRanges());
  2526. if (Parser->SavedDiagHandler)
  2527. Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
  2528. else
  2529. NewDiag.print(nullptr, OS);
  2530. }
  2531. // This is similar to the IsIdentifierChar function in AsmLexer.cpp, but does
  2532. // not accept '.'.
  2533. static bool isMacroParameterChar(char C) {
  2534. return isAlnum(C) || C == '_' || C == '$' || C == '@' || C == '?';
  2535. }
  2536. bool MasmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
  2537. ArrayRef<MCAsmMacroParameter> Parameters,
  2538. ArrayRef<MCAsmMacroArgument> A,
  2539. const std::vector<std::string> &Locals, SMLoc L) {
  2540. unsigned NParameters = Parameters.size();
  2541. if (NParameters != A.size())
  2542. return Error(L, "Wrong number of arguments");
  2543. StringMap<std::string> LocalSymbols;
  2544. std::string Name;
  2545. Name.reserve(6);
  2546. for (StringRef Local : Locals) {
  2547. raw_string_ostream LocalName(Name);
  2548. LocalName << "??"
  2549. << format_hex_no_prefix(LocalCounter++, 4, /*Upper=*/true);
  2550. LocalSymbols.insert({Local, LocalName.str()});
  2551. Name.clear();
  2552. }
  2553. std::optional<char> CurrentQuote;
  2554. while (!Body.empty()) {
  2555. // Scan for the next substitution.
  2556. std::size_t End = Body.size(), Pos = 0;
  2557. std::size_t IdentifierPos = End;
  2558. for (; Pos != End; ++Pos) {
  2559. // Find the next possible macro parameter, including preceding a '&'
  2560. // inside quotes.
  2561. if (Body[Pos] == '&')
  2562. break;
  2563. if (isMacroParameterChar(Body[Pos])) {
  2564. if (!CurrentQuote)
  2565. break;
  2566. if (IdentifierPos == End)
  2567. IdentifierPos = Pos;
  2568. } else {
  2569. IdentifierPos = End;
  2570. }
  2571. // Track quotation status
  2572. if (!CurrentQuote) {
  2573. if (Body[Pos] == '\'' || Body[Pos] == '"')
  2574. CurrentQuote = Body[Pos];
  2575. } else if (Body[Pos] == CurrentQuote) {
  2576. if (Pos + 1 != End && Body[Pos + 1] == CurrentQuote) {
  2577. // Escaped quote, and quotes aren't identifier chars; skip
  2578. ++Pos;
  2579. continue;
  2580. } else {
  2581. CurrentQuote.reset();
  2582. }
  2583. }
  2584. }
  2585. if (IdentifierPos != End) {
  2586. // We've recognized an identifier before an apostrophe inside quotes;
  2587. // check once to see if we can expand it.
  2588. Pos = IdentifierPos;
  2589. IdentifierPos = End;
  2590. }
  2591. // Add the prefix.
  2592. OS << Body.slice(0, Pos);
  2593. // Check if we reached the end.
  2594. if (Pos == End)
  2595. break;
  2596. unsigned I = Pos;
  2597. bool InitialAmpersand = (Body[I] == '&');
  2598. if (InitialAmpersand) {
  2599. ++I;
  2600. ++Pos;
  2601. }
  2602. while (I < End && isMacroParameterChar(Body[I]))
  2603. ++I;
  2604. const char *Begin = Body.data() + Pos;
  2605. StringRef Argument(Begin, I - Pos);
  2606. const std::string ArgumentLower = Argument.lower();
  2607. unsigned Index = 0;
  2608. for (; Index < NParameters; ++Index)
  2609. if (Parameters[Index].Name.equals_insensitive(ArgumentLower))
  2610. break;
  2611. if (Index == NParameters) {
  2612. if (InitialAmpersand)
  2613. OS << '&';
  2614. auto it = LocalSymbols.find(ArgumentLower);
  2615. if (it != LocalSymbols.end())
  2616. OS << it->second;
  2617. else
  2618. OS << Argument;
  2619. Pos = I;
  2620. } else {
  2621. for (const AsmToken &Token : A[Index]) {
  2622. // In MASM, you can write '%expr'.
  2623. // The prefix '%' evaluates the expression 'expr'
  2624. // and uses the result as a string (e.g. replace %(1+2) with the
  2625. // string "3").
  2626. // Here, we identify the integer token which is the result of the
  2627. // absolute expression evaluation and replace it with its string
  2628. // representation.
  2629. if (Token.getString().front() == '%' && Token.is(AsmToken::Integer))
  2630. // Emit an integer value to the buffer.
  2631. OS << Token.getIntVal();
  2632. else
  2633. OS << Token.getString();
  2634. }
  2635. Pos += Argument.size();
  2636. if (Pos < End && Body[Pos] == '&') {
  2637. ++Pos;
  2638. }
  2639. }
  2640. // Update the scan point.
  2641. Body = Body.substr(Pos);
  2642. }
  2643. return false;
  2644. }
  2645. static bool isOperator(AsmToken::TokenKind kind) {
  2646. switch (kind) {
  2647. default:
  2648. return false;
  2649. case AsmToken::Plus:
  2650. case AsmToken::Minus:
  2651. case AsmToken::Tilde:
  2652. case AsmToken::Slash:
  2653. case AsmToken::Star:
  2654. case AsmToken::Dot:
  2655. case AsmToken::Equal:
  2656. case AsmToken::EqualEqual:
  2657. case AsmToken::Pipe:
  2658. case AsmToken::PipePipe:
  2659. case AsmToken::Caret:
  2660. case AsmToken::Amp:
  2661. case AsmToken::AmpAmp:
  2662. case AsmToken::Exclaim:
  2663. case AsmToken::ExclaimEqual:
  2664. case AsmToken::Less:
  2665. case AsmToken::LessEqual:
  2666. case AsmToken::LessLess:
  2667. case AsmToken::LessGreater:
  2668. case AsmToken::Greater:
  2669. case AsmToken::GreaterEqual:
  2670. case AsmToken::GreaterGreater:
  2671. return true;
  2672. }
  2673. }
  2674. namespace {
  2675. class AsmLexerSkipSpaceRAII {
  2676. public:
  2677. AsmLexerSkipSpaceRAII(AsmLexer &Lexer, bool SkipSpace) : Lexer(Lexer) {
  2678. Lexer.setSkipSpace(SkipSpace);
  2679. }
  2680. ~AsmLexerSkipSpaceRAII() {
  2681. Lexer.setSkipSpace(true);
  2682. }
  2683. private:
  2684. AsmLexer &Lexer;
  2685. };
  2686. } // end anonymous namespace
  2687. bool MasmParser::parseMacroArgument(const MCAsmMacroParameter *MP,
  2688. MCAsmMacroArgument &MA,
  2689. AsmToken::TokenKind EndTok) {
  2690. if (MP && MP->Vararg) {
  2691. if (Lexer.isNot(EndTok)) {
  2692. SmallVector<StringRef, 1> Str = parseStringRefsTo(EndTok);
  2693. for (StringRef S : Str) {
  2694. MA.emplace_back(AsmToken::String, S);
  2695. }
  2696. }
  2697. return false;
  2698. }
  2699. SMLoc StrLoc = Lexer.getLoc(), EndLoc;
  2700. if (Lexer.is(AsmToken::Less) && isAngleBracketString(StrLoc, EndLoc)) {
  2701. const char *StrChar = StrLoc.getPointer() + 1;
  2702. const char *EndChar = EndLoc.getPointer() - 1;
  2703. jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
  2704. /// Eat from '<' to '>'.
  2705. Lex();
  2706. MA.emplace_back(AsmToken::String, StringRef(StrChar, EndChar - StrChar));
  2707. return false;
  2708. }
  2709. unsigned ParenLevel = 0;
  2710. // Darwin doesn't use spaces to delmit arguments.
  2711. AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin);
  2712. bool SpaceEaten;
  2713. while (true) {
  2714. SpaceEaten = false;
  2715. if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal))
  2716. return TokError("unexpected token");
  2717. if (ParenLevel == 0) {
  2718. if (Lexer.is(AsmToken::Comma))
  2719. break;
  2720. if (Lexer.is(AsmToken::Space)) {
  2721. SpaceEaten = true;
  2722. Lex(); // Eat spaces.
  2723. }
  2724. // Spaces can delimit parameters, but could also be part an expression.
  2725. // If the token after a space is an operator, add the token and the next
  2726. // one into this argument
  2727. if (!IsDarwin) {
  2728. if (isOperator(Lexer.getKind()) && Lexer.isNot(EndTok)) {
  2729. MA.push_back(getTok());
  2730. Lex();
  2731. // Whitespace after an operator can be ignored.
  2732. if (Lexer.is(AsmToken::Space))
  2733. Lex();
  2734. continue;
  2735. }
  2736. }
  2737. if (SpaceEaten)
  2738. break;
  2739. }
  2740. // handleMacroEntry relies on not advancing the lexer here
  2741. // to be able to fill in the remaining default parameter values
  2742. if (Lexer.is(EndTok) && (EndTok != AsmToken::RParen || ParenLevel == 0))
  2743. break;
  2744. // Adjust the current parentheses level.
  2745. if (Lexer.is(AsmToken::LParen))
  2746. ++ParenLevel;
  2747. else if (Lexer.is(AsmToken::RParen) && ParenLevel)
  2748. --ParenLevel;
  2749. // Append the token to the current argument list.
  2750. MA.push_back(getTok());
  2751. Lex();
  2752. }
  2753. if (ParenLevel != 0)
  2754. return TokError("unbalanced parentheses in argument");
  2755. if (MA.empty() && MP) {
  2756. if (MP->Required) {
  2757. return TokError("missing value for required parameter '" + MP->Name +
  2758. "'");
  2759. } else {
  2760. MA = MP->Value;
  2761. }
  2762. }
  2763. return false;
  2764. }
  2765. // Parse the macro instantiation arguments.
  2766. bool MasmParser::parseMacroArguments(const MCAsmMacro *M,
  2767. MCAsmMacroArguments &A,
  2768. AsmToken::TokenKind EndTok) {
  2769. const unsigned NParameters = M ? M->Parameters.size() : 0;
  2770. bool NamedParametersFound = false;
  2771. SmallVector<SMLoc, 4> FALocs;
  2772. A.resize(NParameters);
  2773. FALocs.resize(NParameters);
  2774. // Parse two kinds of macro invocations:
  2775. // - macros defined without any parameters accept an arbitrary number of them
  2776. // - macros defined with parameters accept at most that many of them
  2777. for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
  2778. ++Parameter) {
  2779. SMLoc IDLoc = Lexer.getLoc();
  2780. MCAsmMacroParameter FA;
  2781. if (Lexer.is(AsmToken::Identifier) && peekTok().is(AsmToken::Equal)) {
  2782. if (parseIdentifier(FA.Name))
  2783. return Error(IDLoc, "invalid argument identifier for formal argument");
  2784. if (Lexer.isNot(AsmToken::Equal))
  2785. return TokError("expected '=' after formal parameter identifier");
  2786. Lex();
  2787. NamedParametersFound = true;
  2788. }
  2789. if (NamedParametersFound && FA.Name.empty())
  2790. return Error(IDLoc, "cannot mix positional and keyword arguments");
  2791. unsigned PI = Parameter;
  2792. if (!FA.Name.empty()) {
  2793. assert(M && "expected macro to be defined");
  2794. unsigned FAI = 0;
  2795. for (FAI = 0; FAI < NParameters; ++FAI)
  2796. if (M->Parameters[FAI].Name == FA.Name)
  2797. break;
  2798. if (FAI >= NParameters) {
  2799. return Error(IDLoc, "parameter named '" + FA.Name +
  2800. "' does not exist for macro '" + M->Name + "'");
  2801. }
  2802. PI = FAI;
  2803. }
  2804. const MCAsmMacroParameter *MP = nullptr;
  2805. if (M && PI < NParameters)
  2806. MP = &M->Parameters[PI];
  2807. SMLoc StrLoc = Lexer.getLoc();
  2808. SMLoc EndLoc;
  2809. if (Lexer.is(AsmToken::Percent)) {
  2810. const MCExpr *AbsoluteExp;
  2811. int64_t Value;
  2812. /// Eat '%'.
  2813. Lex();
  2814. if (parseExpression(AbsoluteExp, EndLoc))
  2815. return false;
  2816. if (!AbsoluteExp->evaluateAsAbsolute(Value,
  2817. getStreamer().getAssemblerPtr()))
  2818. return Error(StrLoc, "expected absolute expression");
  2819. const char *StrChar = StrLoc.getPointer();
  2820. const char *EndChar = EndLoc.getPointer();
  2821. AsmToken newToken(AsmToken::Integer,
  2822. StringRef(StrChar, EndChar - StrChar), Value);
  2823. FA.Value.push_back(newToken);
  2824. } else if (parseMacroArgument(MP, FA.Value, EndTok)) {
  2825. if (M)
  2826. return addErrorSuffix(" in '" + M->Name + "' macro");
  2827. else
  2828. return true;
  2829. }
  2830. if (!FA.Value.empty()) {
  2831. if (A.size() <= PI)
  2832. A.resize(PI + 1);
  2833. A[PI] = FA.Value;
  2834. if (FALocs.size() <= PI)
  2835. FALocs.resize(PI + 1);
  2836. FALocs[PI] = Lexer.getLoc();
  2837. }
  2838. // At the end of the statement, fill in remaining arguments that have
  2839. // default values. If there aren't any, then the next argument is
  2840. // required but missing
  2841. if (Lexer.is(EndTok)) {
  2842. bool Failure = false;
  2843. for (unsigned FAI = 0; FAI < NParameters; ++FAI) {
  2844. if (A[FAI].empty()) {
  2845. if (M->Parameters[FAI].Required) {
  2846. Error(FALocs[FAI].isValid() ? FALocs[FAI] : Lexer.getLoc(),
  2847. "missing value for required parameter "
  2848. "'" +
  2849. M->Parameters[FAI].Name + "' in macro '" + M->Name + "'");
  2850. Failure = true;
  2851. }
  2852. if (!M->Parameters[FAI].Value.empty())
  2853. A[FAI] = M->Parameters[FAI].Value;
  2854. }
  2855. }
  2856. return Failure;
  2857. }
  2858. if (Lexer.is(AsmToken::Comma))
  2859. Lex();
  2860. }
  2861. return TokError("too many positional arguments");
  2862. }
  2863. bool MasmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc,
  2864. AsmToken::TokenKind ArgumentEndTok) {
  2865. // Arbitrarily limit macro nesting depth (default matches 'as'). We can
  2866. // eliminate this, although we should protect against infinite loops.
  2867. unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
  2868. if (ActiveMacros.size() == MaxNestingDepth) {
  2869. std::ostringstream MaxNestingDepthError;
  2870. MaxNestingDepthError << "macros cannot be nested more than "
  2871. << MaxNestingDepth << " levels deep."
  2872. << " Use -asm-macro-max-nesting-depth to increase "
  2873. "this limit.";
  2874. return TokError(MaxNestingDepthError.str());
  2875. }
  2876. MCAsmMacroArguments A;
  2877. if (parseMacroArguments(M, A, ArgumentEndTok))
  2878. return true;
  2879. // Macro instantiation is lexical, unfortunately. We construct a new buffer
  2880. // to hold the macro body with substitutions.
  2881. SmallString<256> Buf;
  2882. StringRef Body = M->Body;
  2883. raw_svector_ostream OS(Buf);
  2884. if (expandMacro(OS, Body, M->Parameters, A, M->Locals, getTok().getLoc()))
  2885. return true;
  2886. // We include the endm in the buffer as our cue to exit the macro
  2887. // instantiation.
  2888. OS << "endm\n";
  2889. std::unique_ptr<MemoryBuffer> Instantiation =
  2890. MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
  2891. // Create the macro instantiation object and add to the current macro
  2892. // instantiation stack.
  2893. MacroInstantiation *MI = new MacroInstantiation{
  2894. NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()};
  2895. ActiveMacros.push_back(MI);
  2896. ++NumOfMacroInstantiations;
  2897. // Jump to the macro instantiation and prime the lexer.
  2898. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
  2899. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
  2900. EndStatementAtEOFStack.push_back(true);
  2901. Lex();
  2902. return false;
  2903. }
  2904. void MasmParser::handleMacroExit() {
  2905. // Jump to the token we should return to, and consume it.
  2906. EndStatementAtEOFStack.pop_back();
  2907. jumpToLoc(ActiveMacros.back()->ExitLoc, ActiveMacros.back()->ExitBuffer,
  2908. EndStatementAtEOFStack.back());
  2909. Lex();
  2910. // Pop the instantiation entry.
  2911. delete ActiveMacros.back();
  2912. ActiveMacros.pop_back();
  2913. }
  2914. bool MasmParser::handleMacroInvocation(const MCAsmMacro *M, SMLoc NameLoc) {
  2915. if (!M->IsFunction)
  2916. return Error(NameLoc, "cannot invoke macro procedure as function");
  2917. if (parseToken(AsmToken::LParen, "invoking macro function '" + M->Name +
  2918. "' requires arguments in parentheses") ||
  2919. handleMacroEntry(M, NameLoc, AsmToken::RParen))
  2920. return true;
  2921. // Parse all statements in the macro, retrieving the exit value when it ends.
  2922. std::string ExitValue;
  2923. SmallVector<AsmRewrite, 4> AsmStrRewrites;
  2924. while (Lexer.isNot(AsmToken::Eof)) {
  2925. ParseStatementInfo Info(&AsmStrRewrites);
  2926. bool Parsed = parseStatement(Info, nullptr);
  2927. if (!Parsed && Info.ExitValue) {
  2928. ExitValue = std::move(*Info.ExitValue);
  2929. break;
  2930. }
  2931. // If we have a Lexer Error we are on an Error Token. Load in Lexer Error
  2932. // for printing ErrMsg via Lex() only if no (presumably better) parser error
  2933. // exists.
  2934. if (Parsed && !hasPendingError() && Lexer.getTok().is(AsmToken::Error)) {
  2935. Lex();
  2936. }
  2937. // parseStatement returned true so may need to emit an error.
  2938. printPendingErrors();
  2939. // Skipping to the next line if needed.
  2940. if (Parsed && !getLexer().isAtStartOfStatement())
  2941. eatToEndOfStatement();
  2942. }
  2943. // Consume the right-parenthesis on the other side of the arguments.
  2944. if (parseRParen())
  2945. return true;
  2946. // Exit values may require lexing, unfortunately. We construct a new buffer to
  2947. // hold the exit value.
  2948. std::unique_ptr<MemoryBuffer> MacroValue =
  2949. MemoryBuffer::getMemBufferCopy(ExitValue, "<macro-value>");
  2950. // Jump from this location to the instantiated exit value, and prime the
  2951. // lexer.
  2952. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(MacroValue), Lexer.getLoc());
  2953. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(), nullptr,
  2954. /*EndStatementAtEOF=*/false);
  2955. EndStatementAtEOFStack.push_back(false);
  2956. Lex();
  2957. return false;
  2958. }
  2959. /// parseIdentifier:
  2960. /// ::= identifier
  2961. /// ::= string
  2962. bool MasmParser::parseIdentifier(StringRef &Res,
  2963. IdentifierPositionKind Position) {
  2964. // The assembler has relaxed rules for accepting identifiers, in particular we
  2965. // allow things like '.globl $foo' and '.def @feat.00', which would normally
  2966. // be separate tokens. At this level, we have already lexed so we cannot
  2967. // (currently) handle this as a context dependent token, instead we detect
  2968. // adjacent tokens and return the combined identifier.
  2969. if (Lexer.is(AsmToken::Dollar) || Lexer.is(AsmToken::At)) {
  2970. SMLoc PrefixLoc = getLexer().getLoc();
  2971. // Consume the prefix character, and check for a following identifier.
  2972. AsmToken nextTok = peekTok(false);
  2973. if (nextTok.isNot(AsmToken::Identifier))
  2974. return true;
  2975. // We have a '$' or '@' followed by an identifier, make sure they are adjacent.
  2976. if (PrefixLoc.getPointer() + 1 != nextTok.getLoc().getPointer())
  2977. return true;
  2978. // eat $ or @
  2979. Lexer.Lex(); // Lexer's Lex guarantees consecutive token.
  2980. // Construct the joined identifier and consume the token.
  2981. Res =
  2982. StringRef(PrefixLoc.getPointer(), getTok().getIdentifier().size() + 1);
  2983. Lex(); // Parser Lex to maintain invariants.
  2984. return false;
  2985. }
  2986. if (Lexer.isNot(AsmToken::Identifier) && Lexer.isNot(AsmToken::String))
  2987. return true;
  2988. Res = getTok().getIdentifier();
  2989. // Consume the identifier token - but if parsing certain directives, avoid
  2990. // lexical expansion of the next token.
  2991. ExpandKind ExpandNextToken = ExpandMacros;
  2992. if (Position == StartOfStatement &&
  2993. StringSwitch<bool>(Res)
  2994. .CaseLower("echo", true)
  2995. .CasesLower("ifdef", "ifndef", "elseifdef", "elseifndef", true)
  2996. .Default(false)) {
  2997. ExpandNextToken = DoNotExpandMacros;
  2998. }
  2999. Lex(ExpandNextToken);
  3000. return false;
  3001. }
  3002. /// parseDirectiveEquate:
  3003. /// ::= name "=" expression
  3004. /// | name "equ" expression (not redefinable)
  3005. /// | name "equ" text-list
  3006. /// | name "textequ" text-list (redefinability unspecified)
  3007. bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name,
  3008. DirectiveKind DirKind, SMLoc NameLoc) {
  3009. auto BuiltinIt = BuiltinSymbolMap.find(Name.lower());
  3010. if (BuiltinIt != BuiltinSymbolMap.end())
  3011. return Error(NameLoc, "cannot redefine a built-in symbol");
  3012. Variable &Var = Variables[Name.lower()];
  3013. if (Var.Name.empty()) {
  3014. Var.Name = Name;
  3015. }
  3016. SMLoc StartLoc = Lexer.getLoc();
  3017. if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) {
  3018. // "equ" and "textequ" both allow text expressions.
  3019. std::string Value;
  3020. std::string TextItem;
  3021. if (!parseTextItem(TextItem)) {
  3022. Value += TextItem;
  3023. // Accept a text-list, not just one text-item.
  3024. auto parseItem = [&]() -> bool {
  3025. if (parseTextItem(TextItem))
  3026. return TokError("expected text item");
  3027. Value += TextItem;
  3028. return false;
  3029. };
  3030. if (parseOptionalToken(AsmToken::Comma) && parseMany(parseItem))
  3031. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3032. if (!Var.IsText || Var.TextValue != Value) {
  3033. switch (Var.Redefinable) {
  3034. case Variable::NOT_REDEFINABLE:
  3035. return Error(getTok().getLoc(), "invalid variable redefinition");
  3036. case Variable::WARN_ON_REDEFINITION:
  3037. if (Warning(NameLoc, "redefining '" + Name +
  3038. "', already defined on the command line")) {
  3039. return true;
  3040. }
  3041. break;
  3042. default:
  3043. break;
  3044. }
  3045. }
  3046. Var.IsText = true;
  3047. Var.TextValue = Value;
  3048. Var.Redefinable = Variable::REDEFINABLE;
  3049. return false;
  3050. }
  3051. }
  3052. if (DirKind == DK_TEXTEQU)
  3053. return TokError("expected <text> in '" + Twine(IDVal) + "' directive");
  3054. // Parse as expression assignment.
  3055. const MCExpr *Expr;
  3056. SMLoc EndLoc;
  3057. if (parseExpression(Expr, EndLoc))
  3058. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3059. StringRef ExprAsString = StringRef(
  3060. StartLoc.getPointer(), EndLoc.getPointer() - StartLoc.getPointer());
  3061. int64_t Value;
  3062. if (!Expr->evaluateAsAbsolute(Value, getStreamer().getAssemblerPtr())) {
  3063. if (DirKind == DK_ASSIGN)
  3064. return Error(
  3065. StartLoc,
  3066. "expected absolute expression; not all symbols have known values",
  3067. {StartLoc, EndLoc});
  3068. // Not an absolute expression; define as a text replacement.
  3069. if (!Var.IsText || Var.TextValue != ExprAsString) {
  3070. switch (Var.Redefinable) {
  3071. case Variable::NOT_REDEFINABLE:
  3072. return Error(getTok().getLoc(), "invalid variable redefinition");
  3073. case Variable::WARN_ON_REDEFINITION:
  3074. if (Warning(NameLoc, "redefining '" + Name +
  3075. "', already defined on the command line")) {
  3076. return true;
  3077. }
  3078. break;
  3079. default:
  3080. break;
  3081. }
  3082. }
  3083. Var.IsText = true;
  3084. Var.TextValue = ExprAsString.str();
  3085. Var.Redefinable = Variable::REDEFINABLE;
  3086. return false;
  3087. }
  3088. MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name);
  3089. const MCConstantExpr *PrevValue =
  3090. Sym->isVariable() ? dyn_cast_or_null<MCConstantExpr>(
  3091. Sym->getVariableValue(/*SetUsed=*/false))
  3092. : nullptr;
  3093. if (Var.IsText || !PrevValue || PrevValue->getValue() != Value) {
  3094. switch (Var.Redefinable) {
  3095. case Variable::NOT_REDEFINABLE:
  3096. return Error(getTok().getLoc(), "invalid variable redefinition");
  3097. case Variable::WARN_ON_REDEFINITION:
  3098. if (Warning(NameLoc, "redefining '" + Name +
  3099. "', already defined on the command line")) {
  3100. return true;
  3101. }
  3102. break;
  3103. default:
  3104. break;
  3105. }
  3106. }
  3107. Var.IsText = false;
  3108. Var.TextValue.clear();
  3109. Var.Redefinable = (DirKind == DK_ASSIGN) ? Variable::REDEFINABLE
  3110. : Variable::NOT_REDEFINABLE;
  3111. Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE);
  3112. Sym->setVariableValue(Expr);
  3113. Sym->setExternal(false);
  3114. return false;
  3115. }
  3116. bool MasmParser::parseEscapedString(std::string &Data) {
  3117. if (check(getTok().isNot(AsmToken::String), "expected string"))
  3118. return true;
  3119. Data = "";
  3120. char Quote = getTok().getString().front();
  3121. StringRef Str = getTok().getStringContents();
  3122. Data.reserve(Str.size());
  3123. for (size_t i = 0, e = Str.size(); i != e; ++i) {
  3124. Data.push_back(Str[i]);
  3125. if (Str[i] == Quote) {
  3126. // MASM treats doubled delimiting quotes as an escaped delimiting quote.
  3127. // If we're escaping the string's trailing delimiter, we're definitely
  3128. // missing a quotation mark.
  3129. if (i + 1 == Str.size())
  3130. return Error(getTok().getLoc(), "missing quotation mark in string");
  3131. if (Str[i + 1] == Quote)
  3132. ++i;
  3133. }
  3134. }
  3135. Lex();
  3136. return false;
  3137. }
  3138. bool MasmParser::parseAngleBracketString(std::string &Data) {
  3139. SMLoc EndLoc, StartLoc = getTok().getLoc();
  3140. if (isAngleBracketString(StartLoc, EndLoc)) {
  3141. const char *StartChar = StartLoc.getPointer() + 1;
  3142. const char *EndChar = EndLoc.getPointer() - 1;
  3143. jumpToLoc(EndLoc, CurBuffer, EndStatementAtEOFStack.back());
  3144. // Eat from '<' to '>'.
  3145. Lex();
  3146. Data = angleBracketString(StringRef(StartChar, EndChar - StartChar));
  3147. return false;
  3148. }
  3149. return true;
  3150. }
  3151. /// textItem ::= textLiteral | textMacroID | % constExpr
  3152. bool MasmParser::parseTextItem(std::string &Data) {
  3153. switch (getTok().getKind()) {
  3154. default:
  3155. return true;
  3156. case AsmToken::Percent: {
  3157. int64_t Res;
  3158. if (parseToken(AsmToken::Percent) || parseAbsoluteExpression(Res))
  3159. return true;
  3160. Data = std::to_string(Res);
  3161. return false;
  3162. }
  3163. case AsmToken::Less:
  3164. case AsmToken::LessEqual:
  3165. case AsmToken::LessLess:
  3166. case AsmToken::LessGreater:
  3167. return parseAngleBracketString(Data);
  3168. case AsmToken::Identifier: {
  3169. // This must be a text macro; we need to expand it accordingly.
  3170. StringRef ID;
  3171. SMLoc StartLoc = getTok().getLoc();
  3172. if (parseIdentifier(ID))
  3173. return true;
  3174. Data = ID.str();
  3175. bool Expanded = false;
  3176. while (true) {
  3177. // Try to resolve as a built-in text macro
  3178. auto BuiltinIt = BuiltinSymbolMap.find(ID.lower());
  3179. if (BuiltinIt != BuiltinSymbolMap.end()) {
  3180. std::optional<std::string> BuiltinText =
  3181. evaluateBuiltinTextMacro(BuiltinIt->getValue(), StartLoc);
  3182. if (!BuiltinText) {
  3183. // Not a text macro; break without substituting
  3184. break;
  3185. }
  3186. Data = std::move(*BuiltinText);
  3187. ID = StringRef(Data);
  3188. Expanded = true;
  3189. continue;
  3190. }
  3191. // Try to resolve as a variable text macro
  3192. auto VarIt = Variables.find(ID.lower());
  3193. if (VarIt != Variables.end()) {
  3194. const Variable &Var = VarIt->getValue();
  3195. if (!Var.IsText) {
  3196. // Not a text macro; break without substituting
  3197. break;
  3198. }
  3199. Data = Var.TextValue;
  3200. ID = StringRef(Data);
  3201. Expanded = true;
  3202. continue;
  3203. }
  3204. break;
  3205. }
  3206. if (!Expanded) {
  3207. // Not a text macro; not usable in TextItem context. Since we haven't used
  3208. // the token, put it back for better error recovery.
  3209. getLexer().UnLex(AsmToken(AsmToken::Identifier, ID));
  3210. return true;
  3211. }
  3212. return false;
  3213. }
  3214. }
  3215. llvm_unreachable("unhandled token kind");
  3216. }
  3217. /// parseDirectiveAscii:
  3218. /// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
  3219. bool MasmParser::parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
  3220. auto parseOp = [&]() -> bool {
  3221. std::string Data;
  3222. if (checkForValidSection() || parseEscapedString(Data))
  3223. return true;
  3224. getStreamer().emitBytes(Data);
  3225. if (ZeroTerminated)
  3226. getStreamer().emitBytes(StringRef("\0", 1));
  3227. return false;
  3228. };
  3229. if (parseMany(parseOp))
  3230. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3231. return false;
  3232. }
  3233. bool MasmParser::emitIntValue(const MCExpr *Value, unsigned Size) {
  3234. // Special case constant expressions to match code generator.
  3235. if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
  3236. assert(Size <= 8 && "Invalid size");
  3237. int64_t IntValue = MCE->getValue();
  3238. if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
  3239. return Error(MCE->getLoc(), "out of range literal value");
  3240. getStreamer().emitIntValue(IntValue, Size);
  3241. } else {
  3242. const MCSymbolRefExpr *MSE = dyn_cast<MCSymbolRefExpr>(Value);
  3243. if (MSE && MSE->getSymbol().getName() == "?") {
  3244. // ? initializer; treat as 0.
  3245. getStreamer().emitIntValue(0, Size);
  3246. } else {
  3247. getStreamer().emitValue(Value, Size, Value->getLoc());
  3248. }
  3249. }
  3250. return false;
  3251. }
  3252. bool MasmParser::parseScalarInitializer(unsigned Size,
  3253. SmallVectorImpl<const MCExpr *> &Values,
  3254. unsigned StringPadLength) {
  3255. if (Size == 1 && getTok().is(AsmToken::String)) {
  3256. std::string Value;
  3257. if (parseEscapedString(Value))
  3258. return true;
  3259. // Treat each character as an initializer.
  3260. for (const unsigned char CharVal : Value)
  3261. Values.push_back(MCConstantExpr::create(CharVal, getContext()));
  3262. // Pad the string with spaces to the specified length.
  3263. for (size_t i = Value.size(); i < StringPadLength; ++i)
  3264. Values.push_back(MCConstantExpr::create(' ', getContext()));
  3265. } else {
  3266. const MCExpr *Value;
  3267. if (parseExpression(Value))
  3268. return true;
  3269. if (getTok().is(AsmToken::Identifier) &&
  3270. getTok().getString().equals_insensitive("dup")) {
  3271. Lex(); // Eat 'dup'.
  3272. const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
  3273. if (!MCE)
  3274. return Error(Value->getLoc(),
  3275. "cannot repeat value a non-constant number of times");
  3276. const int64_t Repetitions = MCE->getValue();
  3277. if (Repetitions < 0)
  3278. return Error(Value->getLoc(),
  3279. "cannot repeat value a negative number of times");
  3280. SmallVector<const MCExpr *, 1> DuplicatedValues;
  3281. if (parseToken(AsmToken::LParen,
  3282. "parentheses required for 'dup' contents") ||
  3283. parseScalarInstList(Size, DuplicatedValues) || parseRParen())
  3284. return true;
  3285. for (int i = 0; i < Repetitions; ++i)
  3286. Values.append(DuplicatedValues.begin(), DuplicatedValues.end());
  3287. } else {
  3288. Values.push_back(Value);
  3289. }
  3290. }
  3291. return false;
  3292. }
  3293. bool MasmParser::parseScalarInstList(unsigned Size,
  3294. SmallVectorImpl<const MCExpr *> &Values,
  3295. const AsmToken::TokenKind EndToken) {
  3296. while (getTok().isNot(EndToken) &&
  3297. (EndToken != AsmToken::Greater ||
  3298. getTok().isNot(AsmToken::GreaterGreater))) {
  3299. parseScalarInitializer(Size, Values);
  3300. // If we see a comma, continue, and allow line continuation.
  3301. if (!parseOptionalToken(AsmToken::Comma))
  3302. break;
  3303. parseOptionalToken(AsmToken::EndOfStatement);
  3304. }
  3305. return false;
  3306. }
  3307. bool MasmParser::emitIntegralValues(unsigned Size, unsigned *Count) {
  3308. SmallVector<const MCExpr *, 1> Values;
  3309. if (checkForValidSection() || parseScalarInstList(Size, Values))
  3310. return true;
  3311. for (const auto *Value : Values) {
  3312. emitIntValue(Value, Size);
  3313. }
  3314. if (Count)
  3315. *Count = Values.size();
  3316. return false;
  3317. }
  3318. // Add a field to the current structure.
  3319. bool MasmParser::addIntegralField(StringRef Name, unsigned Size) {
  3320. StructInfo &Struct = StructInProgress.back();
  3321. FieldInfo &Field = Struct.addField(Name, FT_INTEGRAL, Size);
  3322. IntFieldInfo &IntInfo = Field.Contents.IntInfo;
  3323. Field.Type = Size;
  3324. if (parseScalarInstList(Size, IntInfo.Values))
  3325. return true;
  3326. Field.SizeOf = Field.Type * IntInfo.Values.size();
  3327. Field.LengthOf = IntInfo.Values.size();
  3328. const unsigned FieldEnd = Field.Offset + Field.SizeOf;
  3329. if (!Struct.IsUnion) {
  3330. Struct.NextOffset = FieldEnd;
  3331. }
  3332. Struct.Size = std::max(Struct.Size, FieldEnd);
  3333. return false;
  3334. }
  3335. /// parseDirectiveValue
  3336. /// ::= (byte | word | ... ) [ expression (, expression)* ]
  3337. bool MasmParser::parseDirectiveValue(StringRef IDVal, unsigned Size) {
  3338. if (StructInProgress.empty()) {
  3339. // Initialize data value.
  3340. if (emitIntegralValues(Size))
  3341. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3342. } else if (addIntegralField("", Size)) {
  3343. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3344. }
  3345. return false;
  3346. }
  3347. /// parseDirectiveNamedValue
  3348. /// ::= name (byte | word | ... ) [ expression (, expression)* ]
  3349. bool MasmParser::parseDirectiveNamedValue(StringRef TypeName, unsigned Size,
  3350. StringRef Name, SMLoc NameLoc) {
  3351. if (StructInProgress.empty()) {
  3352. // Initialize named data value.
  3353. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  3354. getStreamer().emitLabel(Sym);
  3355. unsigned Count;
  3356. if (emitIntegralValues(Size, &Count))
  3357. return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
  3358. AsmTypeInfo Type;
  3359. Type.Name = TypeName;
  3360. Type.Size = Size * Count;
  3361. Type.ElementSize = Size;
  3362. Type.Length = Count;
  3363. KnownType[Name.lower()] = Type;
  3364. } else if (addIntegralField(Name, Size)) {
  3365. return addErrorSuffix(" in '" + Twine(TypeName) + "' directive");
  3366. }
  3367. return false;
  3368. }
  3369. static bool parseHexOcta(MasmParser &Asm, uint64_t &hi, uint64_t &lo) {
  3370. if (Asm.getTok().isNot(AsmToken::Integer) &&
  3371. Asm.getTok().isNot(AsmToken::BigNum))
  3372. return Asm.TokError("unknown token in expression");
  3373. SMLoc ExprLoc = Asm.getTok().getLoc();
  3374. APInt IntValue = Asm.getTok().getAPIntVal();
  3375. Asm.Lex();
  3376. if (!IntValue.isIntN(128))
  3377. return Asm.Error(ExprLoc, "out of range literal value");
  3378. if (!IntValue.isIntN(64)) {
  3379. hi = IntValue.getHiBits(IntValue.getBitWidth() - 64).getZExtValue();
  3380. lo = IntValue.getLoBits(64).getZExtValue();
  3381. } else {
  3382. hi = 0;
  3383. lo = IntValue.getZExtValue();
  3384. }
  3385. return false;
  3386. }
  3387. bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
  3388. // We don't truly support arithmetic on floating point expressions, so we
  3389. // have to manually parse unary prefixes.
  3390. bool IsNeg = false;
  3391. SMLoc SignLoc;
  3392. if (getLexer().is(AsmToken::Minus)) {
  3393. SignLoc = getLexer().getLoc();
  3394. Lexer.Lex();
  3395. IsNeg = true;
  3396. } else if (getLexer().is(AsmToken::Plus)) {
  3397. SignLoc = getLexer().getLoc();
  3398. Lexer.Lex();
  3399. }
  3400. if (Lexer.is(AsmToken::Error))
  3401. return TokError(Lexer.getErr());
  3402. if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
  3403. Lexer.isNot(AsmToken::Identifier))
  3404. return TokError("unexpected token in directive");
  3405. // Convert to an APFloat.
  3406. APFloat Value(Semantics);
  3407. StringRef IDVal = getTok().getString();
  3408. if (getLexer().is(AsmToken::Identifier)) {
  3409. if (IDVal.equals_insensitive("infinity") || IDVal.equals_insensitive("inf"))
  3410. Value = APFloat::getInf(Semantics);
  3411. else if (IDVal.equals_insensitive("nan"))
  3412. Value = APFloat::getNaN(Semantics, false, ~0);
  3413. else if (IDVal.equals_insensitive("?"))
  3414. Value = APFloat::getZero(Semantics);
  3415. else
  3416. return TokError("invalid floating point literal");
  3417. } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) {
  3418. // MASM hexadecimal floating-point literal; no APFloat conversion needed.
  3419. // To match ML64.exe, ignore the initial sign.
  3420. unsigned SizeInBits = Value.getSizeInBits(Semantics);
  3421. if (SizeInBits != (IDVal.size() << 2))
  3422. return TokError("invalid floating point literal");
  3423. // Consume the numeric token.
  3424. Lex();
  3425. Res = APInt(SizeInBits, IDVal, 16);
  3426. if (SignLoc.isValid())
  3427. return Warning(SignLoc, "MASM-style hex floats ignore explicit sign");
  3428. return false;
  3429. } else if (errorToBool(
  3430. Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven)
  3431. .takeError())) {
  3432. return TokError("invalid floating point literal");
  3433. }
  3434. if (IsNeg)
  3435. Value.changeSign();
  3436. // Consume the numeric token.
  3437. Lex();
  3438. Res = Value.bitcastToAPInt();
  3439. return false;
  3440. }
  3441. bool MasmParser::parseRealInstList(const fltSemantics &Semantics,
  3442. SmallVectorImpl<APInt> &ValuesAsInt,
  3443. const AsmToken::TokenKind EndToken) {
  3444. while (getTok().isNot(EndToken) ||
  3445. (EndToken == AsmToken::Greater &&
  3446. getTok().isNot(AsmToken::GreaterGreater))) {
  3447. const AsmToken NextTok = peekTok();
  3448. if (NextTok.is(AsmToken::Identifier) &&
  3449. NextTok.getString().equals_insensitive("dup")) {
  3450. const MCExpr *Value;
  3451. if (parseExpression(Value) || parseToken(AsmToken::Identifier))
  3452. return true;
  3453. const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
  3454. if (!MCE)
  3455. return Error(Value->getLoc(),
  3456. "cannot repeat value a non-constant number of times");
  3457. const int64_t Repetitions = MCE->getValue();
  3458. if (Repetitions < 0)
  3459. return Error(Value->getLoc(),
  3460. "cannot repeat value a negative number of times");
  3461. SmallVector<APInt, 1> DuplicatedValues;
  3462. if (parseToken(AsmToken::LParen,
  3463. "parentheses required for 'dup' contents") ||
  3464. parseRealInstList(Semantics, DuplicatedValues) || parseRParen())
  3465. return true;
  3466. for (int i = 0; i < Repetitions; ++i)
  3467. ValuesAsInt.append(DuplicatedValues.begin(), DuplicatedValues.end());
  3468. } else {
  3469. APInt AsInt;
  3470. if (parseRealValue(Semantics, AsInt))
  3471. return true;
  3472. ValuesAsInt.push_back(AsInt);
  3473. }
  3474. // Continue if we see a comma. (Also, allow line continuation.)
  3475. if (!parseOptionalToken(AsmToken::Comma))
  3476. break;
  3477. parseOptionalToken(AsmToken::EndOfStatement);
  3478. }
  3479. return false;
  3480. }
  3481. // Initialize real data values.
  3482. bool MasmParser::emitRealValues(const fltSemantics &Semantics,
  3483. unsigned *Count) {
  3484. if (checkForValidSection())
  3485. return true;
  3486. SmallVector<APInt, 1> ValuesAsInt;
  3487. if (parseRealInstList(Semantics, ValuesAsInt))
  3488. return true;
  3489. for (const APInt &AsInt : ValuesAsInt) {
  3490. getStreamer().emitIntValue(AsInt);
  3491. }
  3492. if (Count)
  3493. *Count = ValuesAsInt.size();
  3494. return false;
  3495. }
  3496. // Add a real field to the current struct.
  3497. bool MasmParser::addRealField(StringRef Name, const fltSemantics &Semantics,
  3498. size_t Size) {
  3499. StructInfo &Struct = StructInProgress.back();
  3500. FieldInfo &Field = Struct.addField(Name, FT_REAL, Size);
  3501. RealFieldInfo &RealInfo = Field.Contents.RealInfo;
  3502. Field.SizeOf = 0;
  3503. if (parseRealInstList(Semantics, RealInfo.AsIntValues))
  3504. return true;
  3505. Field.Type = RealInfo.AsIntValues.back().getBitWidth() / 8;
  3506. Field.LengthOf = RealInfo.AsIntValues.size();
  3507. Field.SizeOf = Field.Type * Field.LengthOf;
  3508. const unsigned FieldEnd = Field.Offset + Field.SizeOf;
  3509. if (!Struct.IsUnion) {
  3510. Struct.NextOffset = FieldEnd;
  3511. }
  3512. Struct.Size = std::max(Struct.Size, FieldEnd);
  3513. return false;
  3514. }
  3515. /// parseDirectiveRealValue
  3516. /// ::= (real4 | real8 | real10) [ expression (, expression)* ]
  3517. bool MasmParser::parseDirectiveRealValue(StringRef IDVal,
  3518. const fltSemantics &Semantics,
  3519. size_t Size) {
  3520. if (StructInProgress.empty()) {
  3521. // Initialize data value.
  3522. if (emitRealValues(Semantics))
  3523. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3524. } else if (addRealField("", Semantics, Size)) {
  3525. return addErrorSuffix(" in '" + Twine(IDVal) + "' directive");
  3526. }
  3527. return false;
  3528. }
  3529. /// parseDirectiveNamedRealValue
  3530. /// ::= name (real4 | real8 | real10) [ expression (, expression)* ]
  3531. bool MasmParser::parseDirectiveNamedRealValue(StringRef TypeName,
  3532. const fltSemantics &Semantics,
  3533. unsigned Size, StringRef Name,
  3534. SMLoc NameLoc) {
  3535. if (StructInProgress.empty()) {
  3536. // Initialize named data value.
  3537. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  3538. getStreamer().emitLabel(Sym);
  3539. unsigned Count;
  3540. if (emitRealValues(Semantics, &Count))
  3541. return addErrorSuffix(" in '" + TypeName + "' directive");
  3542. AsmTypeInfo Type;
  3543. Type.Name = TypeName;
  3544. Type.Size = Size * Count;
  3545. Type.ElementSize = Size;
  3546. Type.Length = Count;
  3547. KnownType[Name.lower()] = Type;
  3548. } else if (addRealField(Name, Semantics, Size)) {
  3549. return addErrorSuffix(" in '" + TypeName + "' directive");
  3550. }
  3551. return false;
  3552. }
  3553. bool MasmParser::parseOptionalAngleBracketOpen() {
  3554. const AsmToken Tok = getTok();
  3555. if (parseOptionalToken(AsmToken::LessLess)) {
  3556. AngleBracketDepth++;
  3557. Lexer.UnLex(AsmToken(AsmToken::Less, Tok.getString().substr(1)));
  3558. return true;
  3559. } else if (parseOptionalToken(AsmToken::LessGreater)) {
  3560. AngleBracketDepth++;
  3561. Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
  3562. return true;
  3563. } else if (parseOptionalToken(AsmToken::Less)) {
  3564. AngleBracketDepth++;
  3565. return true;
  3566. }
  3567. return false;
  3568. }
  3569. bool MasmParser::parseAngleBracketClose(const Twine &Msg) {
  3570. const AsmToken Tok = getTok();
  3571. if (parseOptionalToken(AsmToken::GreaterGreater)) {
  3572. Lexer.UnLex(AsmToken(AsmToken::Greater, Tok.getString().substr(1)));
  3573. } else if (parseToken(AsmToken::Greater, Msg)) {
  3574. return true;
  3575. }
  3576. AngleBracketDepth--;
  3577. return false;
  3578. }
  3579. bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
  3580. const IntFieldInfo &Contents,
  3581. FieldInitializer &Initializer) {
  3582. SMLoc Loc = getTok().getLoc();
  3583. SmallVector<const MCExpr *, 1> Values;
  3584. if (parseOptionalToken(AsmToken::LCurly)) {
  3585. if (Field.LengthOf == 1 && Field.Type > 1)
  3586. return Error(Loc, "Cannot initialize scalar field with array value");
  3587. if (parseScalarInstList(Field.Type, Values, AsmToken::RCurly) ||
  3588. parseToken(AsmToken::RCurly))
  3589. return true;
  3590. } else if (parseOptionalAngleBracketOpen()) {
  3591. if (Field.LengthOf == 1 && Field.Type > 1)
  3592. return Error(Loc, "Cannot initialize scalar field with array value");
  3593. if (parseScalarInstList(Field.Type, Values, AsmToken::Greater) ||
  3594. parseAngleBracketClose())
  3595. return true;
  3596. } else if (Field.LengthOf > 1 && Field.Type > 1) {
  3597. return Error(Loc, "Cannot initialize array field with scalar value");
  3598. } else if (parseScalarInitializer(Field.Type, Values,
  3599. /*StringPadLength=*/Field.LengthOf)) {
  3600. return true;
  3601. }
  3602. if (Values.size() > Field.LengthOf) {
  3603. return Error(Loc, "Initializer too long for field; expected at most " +
  3604. std::to_string(Field.LengthOf) + " elements, got " +
  3605. std::to_string(Values.size()));
  3606. }
  3607. // Default-initialize all remaining values.
  3608. Values.append(Contents.Values.begin() + Values.size(), Contents.Values.end());
  3609. Initializer = FieldInitializer(std::move(Values));
  3610. return false;
  3611. }
  3612. bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
  3613. const RealFieldInfo &Contents,
  3614. FieldInitializer &Initializer) {
  3615. const fltSemantics *Semantics;
  3616. switch (Field.Type) {
  3617. case 4:
  3618. Semantics = &APFloat::IEEEsingle();
  3619. break;
  3620. case 8:
  3621. Semantics = &APFloat::IEEEdouble();
  3622. break;
  3623. case 10:
  3624. Semantics = &APFloat::x87DoubleExtended();
  3625. break;
  3626. default:
  3627. llvm_unreachable("unknown real field type");
  3628. }
  3629. SMLoc Loc = getTok().getLoc();
  3630. SmallVector<APInt, 1> AsIntValues;
  3631. if (parseOptionalToken(AsmToken::LCurly)) {
  3632. if (Field.LengthOf == 1)
  3633. return Error(Loc, "Cannot initialize scalar field with array value");
  3634. if (parseRealInstList(*Semantics, AsIntValues, AsmToken::RCurly) ||
  3635. parseToken(AsmToken::RCurly))
  3636. return true;
  3637. } else if (parseOptionalAngleBracketOpen()) {
  3638. if (Field.LengthOf == 1)
  3639. return Error(Loc, "Cannot initialize scalar field with array value");
  3640. if (parseRealInstList(*Semantics, AsIntValues, AsmToken::Greater) ||
  3641. parseAngleBracketClose())
  3642. return true;
  3643. } else if (Field.LengthOf > 1) {
  3644. return Error(Loc, "Cannot initialize array field with scalar value");
  3645. } else {
  3646. AsIntValues.emplace_back();
  3647. if (parseRealValue(*Semantics, AsIntValues.back()))
  3648. return true;
  3649. }
  3650. if (AsIntValues.size() > Field.LengthOf) {
  3651. return Error(Loc, "Initializer too long for field; expected at most " +
  3652. std::to_string(Field.LengthOf) + " elements, got " +
  3653. std::to_string(AsIntValues.size()));
  3654. }
  3655. // Default-initialize all remaining values.
  3656. AsIntValues.append(Contents.AsIntValues.begin() + AsIntValues.size(),
  3657. Contents.AsIntValues.end());
  3658. Initializer = FieldInitializer(std::move(AsIntValues));
  3659. return false;
  3660. }
  3661. bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
  3662. const StructFieldInfo &Contents,
  3663. FieldInitializer &Initializer) {
  3664. SMLoc Loc = getTok().getLoc();
  3665. std::vector<StructInitializer> Initializers;
  3666. if (Field.LengthOf > 1) {
  3667. if (parseOptionalToken(AsmToken::LCurly)) {
  3668. if (parseStructInstList(Contents.Structure, Initializers,
  3669. AsmToken::RCurly) ||
  3670. parseToken(AsmToken::RCurly))
  3671. return true;
  3672. } else if (parseOptionalAngleBracketOpen()) {
  3673. if (parseStructInstList(Contents.Structure, Initializers,
  3674. AsmToken::Greater) ||
  3675. parseAngleBracketClose())
  3676. return true;
  3677. } else {
  3678. return Error(Loc, "Cannot initialize array field with scalar value");
  3679. }
  3680. } else {
  3681. Initializers.emplace_back();
  3682. if (parseStructInitializer(Contents.Structure, Initializers.back()))
  3683. return true;
  3684. }
  3685. if (Initializers.size() > Field.LengthOf) {
  3686. return Error(Loc, "Initializer too long for field; expected at most " +
  3687. std::to_string(Field.LengthOf) + " elements, got " +
  3688. std::to_string(Initializers.size()));
  3689. }
  3690. // Default-initialize all remaining values.
  3691. Initializers.insert(Initializers.end(),
  3692. Contents.Initializers.begin() + Initializers.size(),
  3693. Contents.Initializers.end());
  3694. Initializer = FieldInitializer(std::move(Initializers), Contents.Structure);
  3695. return false;
  3696. }
  3697. bool MasmParser::parseFieldInitializer(const FieldInfo &Field,
  3698. FieldInitializer &Initializer) {
  3699. switch (Field.Contents.FT) {
  3700. case FT_INTEGRAL:
  3701. return parseFieldInitializer(Field, Field.Contents.IntInfo, Initializer);
  3702. case FT_REAL:
  3703. return parseFieldInitializer(Field, Field.Contents.RealInfo, Initializer);
  3704. case FT_STRUCT:
  3705. return parseFieldInitializer(Field, Field.Contents.StructInfo, Initializer);
  3706. }
  3707. llvm_unreachable("Unhandled FieldType enum");
  3708. }
  3709. bool MasmParser::parseStructInitializer(const StructInfo &Structure,
  3710. StructInitializer &Initializer) {
  3711. const AsmToken FirstToken = getTok();
  3712. std::optional<AsmToken::TokenKind> EndToken;
  3713. if (parseOptionalToken(AsmToken::LCurly)) {
  3714. EndToken = AsmToken::RCurly;
  3715. } else if (parseOptionalAngleBracketOpen()) {
  3716. EndToken = AsmToken::Greater;
  3717. AngleBracketDepth++;
  3718. } else if (FirstToken.is(AsmToken::Identifier) &&
  3719. FirstToken.getString() == "?") {
  3720. // ? initializer; leave EndToken uninitialized to treat as empty.
  3721. if (parseToken(AsmToken::Identifier))
  3722. return true;
  3723. } else {
  3724. return Error(FirstToken.getLoc(), "Expected struct initializer");
  3725. }
  3726. auto &FieldInitializers = Initializer.FieldInitializers;
  3727. size_t FieldIndex = 0;
  3728. if (EndToken) {
  3729. // Initialize all fields with given initializers.
  3730. while (getTok().isNot(*EndToken) && FieldIndex < Structure.Fields.size()) {
  3731. const FieldInfo &Field = Structure.Fields[FieldIndex++];
  3732. if (parseOptionalToken(AsmToken::Comma)) {
  3733. // Empty initializer; use the default and continue. (Also, allow line
  3734. // continuation.)
  3735. FieldInitializers.push_back(Field.Contents);
  3736. parseOptionalToken(AsmToken::EndOfStatement);
  3737. continue;
  3738. }
  3739. FieldInitializers.emplace_back(Field.Contents.FT);
  3740. if (parseFieldInitializer(Field, FieldInitializers.back()))
  3741. return true;
  3742. // Continue if we see a comma. (Also, allow line continuation.)
  3743. SMLoc CommaLoc = getTok().getLoc();
  3744. if (!parseOptionalToken(AsmToken::Comma))
  3745. break;
  3746. if (FieldIndex == Structure.Fields.size())
  3747. return Error(CommaLoc, "'" + Structure.Name +
  3748. "' initializer initializes too many fields");
  3749. parseOptionalToken(AsmToken::EndOfStatement);
  3750. }
  3751. }
  3752. // Default-initialize all remaining fields.
  3753. for (const FieldInfo &Field : llvm::drop_begin(Structure.Fields, FieldIndex))
  3754. FieldInitializers.push_back(Field.Contents);
  3755. if (EndToken) {
  3756. if (*EndToken == AsmToken::Greater)
  3757. return parseAngleBracketClose();
  3758. return parseToken(*EndToken);
  3759. }
  3760. return false;
  3761. }
  3762. bool MasmParser::parseStructInstList(
  3763. const StructInfo &Structure, std::vector<StructInitializer> &Initializers,
  3764. const AsmToken::TokenKind EndToken) {
  3765. while (getTok().isNot(EndToken) ||
  3766. (EndToken == AsmToken::Greater &&
  3767. getTok().isNot(AsmToken::GreaterGreater))) {
  3768. const AsmToken NextTok = peekTok();
  3769. if (NextTok.is(AsmToken::Identifier) &&
  3770. NextTok.getString().equals_insensitive("dup")) {
  3771. const MCExpr *Value;
  3772. if (parseExpression(Value) || parseToken(AsmToken::Identifier))
  3773. return true;
  3774. const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
  3775. if (!MCE)
  3776. return Error(Value->getLoc(),
  3777. "cannot repeat value a non-constant number of times");
  3778. const int64_t Repetitions = MCE->getValue();
  3779. if (Repetitions < 0)
  3780. return Error(Value->getLoc(),
  3781. "cannot repeat value a negative number of times");
  3782. std::vector<StructInitializer> DuplicatedValues;
  3783. if (parseToken(AsmToken::LParen,
  3784. "parentheses required for 'dup' contents") ||
  3785. parseStructInstList(Structure, DuplicatedValues) || parseRParen())
  3786. return true;
  3787. for (int i = 0; i < Repetitions; ++i)
  3788. llvm::append_range(Initializers, DuplicatedValues);
  3789. } else {
  3790. Initializers.emplace_back();
  3791. if (parseStructInitializer(Structure, Initializers.back()))
  3792. return true;
  3793. }
  3794. // Continue if we see a comma. (Also, allow line continuation.)
  3795. if (!parseOptionalToken(AsmToken::Comma))
  3796. break;
  3797. parseOptionalToken(AsmToken::EndOfStatement);
  3798. }
  3799. return false;
  3800. }
  3801. bool MasmParser::emitFieldValue(const FieldInfo &Field,
  3802. const IntFieldInfo &Contents) {
  3803. // Default-initialize all values.
  3804. for (const MCExpr *Value : Contents.Values) {
  3805. if (emitIntValue(Value, Field.Type))
  3806. return true;
  3807. }
  3808. return false;
  3809. }
  3810. bool MasmParser::emitFieldValue(const FieldInfo &Field,
  3811. const RealFieldInfo &Contents) {
  3812. for (const APInt &AsInt : Contents.AsIntValues) {
  3813. getStreamer().emitIntValue(AsInt.getLimitedValue(),
  3814. AsInt.getBitWidth() / 8);
  3815. }
  3816. return false;
  3817. }
  3818. bool MasmParser::emitFieldValue(const FieldInfo &Field,
  3819. const StructFieldInfo &Contents) {
  3820. for (const auto &Initializer : Contents.Initializers) {
  3821. size_t Index = 0, Offset = 0;
  3822. for (const auto &SubField : Contents.Structure.Fields) {
  3823. getStreamer().emitZeros(SubField.Offset - Offset);
  3824. Offset = SubField.Offset + SubField.SizeOf;
  3825. emitFieldInitializer(SubField, Initializer.FieldInitializers[Index++]);
  3826. }
  3827. }
  3828. return false;
  3829. }
  3830. bool MasmParser::emitFieldValue(const FieldInfo &Field) {
  3831. switch (Field.Contents.FT) {
  3832. case FT_INTEGRAL:
  3833. return emitFieldValue(Field, Field.Contents.IntInfo);
  3834. case FT_REAL:
  3835. return emitFieldValue(Field, Field.Contents.RealInfo);
  3836. case FT_STRUCT:
  3837. return emitFieldValue(Field, Field.Contents.StructInfo);
  3838. }
  3839. llvm_unreachable("Unhandled FieldType enum");
  3840. }
  3841. bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
  3842. const IntFieldInfo &Contents,
  3843. const IntFieldInfo &Initializer) {
  3844. for (const auto &Value : Initializer.Values) {
  3845. if (emitIntValue(Value, Field.Type))
  3846. return true;
  3847. }
  3848. // Default-initialize all remaining values.
  3849. for (const auto &Value :
  3850. llvm::drop_begin(Contents.Values, Initializer.Values.size())) {
  3851. if (emitIntValue(Value, Field.Type))
  3852. return true;
  3853. }
  3854. return false;
  3855. }
  3856. bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
  3857. const RealFieldInfo &Contents,
  3858. const RealFieldInfo &Initializer) {
  3859. for (const auto &AsInt : Initializer.AsIntValues) {
  3860. getStreamer().emitIntValue(AsInt.getLimitedValue(),
  3861. AsInt.getBitWidth() / 8);
  3862. }
  3863. // Default-initialize all remaining values.
  3864. for (const auto &AsInt :
  3865. llvm::drop_begin(Contents.AsIntValues, Initializer.AsIntValues.size())) {
  3866. getStreamer().emitIntValue(AsInt.getLimitedValue(),
  3867. AsInt.getBitWidth() / 8);
  3868. }
  3869. return false;
  3870. }
  3871. bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
  3872. const StructFieldInfo &Contents,
  3873. const StructFieldInfo &Initializer) {
  3874. for (const auto &Init : Initializer.Initializers) {
  3875. if (emitStructInitializer(Contents.Structure, Init))
  3876. return true;
  3877. }
  3878. // Default-initialize all remaining values.
  3879. for (const auto &Init : llvm::drop_begin(Contents.Initializers,
  3880. Initializer.Initializers.size())) {
  3881. if (emitStructInitializer(Contents.Structure, Init))
  3882. return true;
  3883. }
  3884. return false;
  3885. }
  3886. bool MasmParser::emitFieldInitializer(const FieldInfo &Field,
  3887. const FieldInitializer &Initializer) {
  3888. switch (Field.Contents.FT) {
  3889. case FT_INTEGRAL:
  3890. return emitFieldInitializer(Field, Field.Contents.IntInfo,
  3891. Initializer.IntInfo);
  3892. case FT_REAL:
  3893. return emitFieldInitializer(Field, Field.Contents.RealInfo,
  3894. Initializer.RealInfo);
  3895. case FT_STRUCT:
  3896. return emitFieldInitializer(Field, Field.Contents.StructInfo,
  3897. Initializer.StructInfo);
  3898. }
  3899. llvm_unreachable("Unhandled FieldType enum");
  3900. }
  3901. bool MasmParser::emitStructInitializer(const StructInfo &Structure,
  3902. const StructInitializer &Initializer) {
  3903. if (!Structure.Initializable)
  3904. return Error(getLexer().getLoc(),
  3905. "cannot initialize a value of type '" + Structure.Name +
  3906. "'; 'org' was used in the type's declaration");
  3907. size_t Index = 0, Offset = 0;
  3908. for (const auto &Init : Initializer.FieldInitializers) {
  3909. const auto &Field = Structure.Fields[Index++];
  3910. getStreamer().emitZeros(Field.Offset - Offset);
  3911. Offset = Field.Offset + Field.SizeOf;
  3912. if (emitFieldInitializer(Field, Init))
  3913. return true;
  3914. }
  3915. // Default-initialize all remaining fields.
  3916. for (const auto &Field : llvm::drop_begin(
  3917. Structure.Fields, Initializer.FieldInitializers.size())) {
  3918. getStreamer().emitZeros(Field.Offset - Offset);
  3919. Offset = Field.Offset + Field.SizeOf;
  3920. if (emitFieldValue(Field))
  3921. return true;
  3922. }
  3923. // Add final padding.
  3924. if (Offset != Structure.Size)
  3925. getStreamer().emitZeros(Structure.Size - Offset);
  3926. return false;
  3927. }
  3928. // Set data values from initializers.
  3929. bool MasmParser::emitStructValues(const StructInfo &Structure,
  3930. unsigned *Count) {
  3931. std::vector<StructInitializer> Initializers;
  3932. if (parseStructInstList(Structure, Initializers))
  3933. return true;
  3934. for (const auto &Initializer : Initializers) {
  3935. if (emitStructInitializer(Structure, Initializer))
  3936. return true;
  3937. }
  3938. if (Count)
  3939. *Count = Initializers.size();
  3940. return false;
  3941. }
  3942. // Declare a field in the current struct.
  3943. bool MasmParser::addStructField(StringRef Name, const StructInfo &Structure) {
  3944. StructInfo &OwningStruct = StructInProgress.back();
  3945. FieldInfo &Field =
  3946. OwningStruct.addField(Name, FT_STRUCT, Structure.AlignmentSize);
  3947. StructFieldInfo &StructInfo = Field.Contents.StructInfo;
  3948. StructInfo.Structure = Structure;
  3949. Field.Type = Structure.Size;
  3950. if (parseStructInstList(Structure, StructInfo.Initializers))
  3951. return true;
  3952. Field.LengthOf = StructInfo.Initializers.size();
  3953. Field.SizeOf = Field.Type * Field.LengthOf;
  3954. const unsigned FieldEnd = Field.Offset + Field.SizeOf;
  3955. if (!OwningStruct.IsUnion) {
  3956. OwningStruct.NextOffset = FieldEnd;
  3957. }
  3958. OwningStruct.Size = std::max(OwningStruct.Size, FieldEnd);
  3959. return false;
  3960. }
  3961. /// parseDirectiveStructValue
  3962. /// ::= struct-id (<struct-initializer> | {struct-initializer})
  3963. /// [, (<struct-initializer> | {struct-initializer})]*
  3964. bool MasmParser::parseDirectiveStructValue(const StructInfo &Structure,
  3965. StringRef Directive, SMLoc DirLoc) {
  3966. if (StructInProgress.empty()) {
  3967. if (emitStructValues(Structure))
  3968. return true;
  3969. } else if (addStructField("", Structure)) {
  3970. return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
  3971. }
  3972. return false;
  3973. }
  3974. /// parseDirectiveNamedValue
  3975. /// ::= name (byte | word | ... ) [ expression (, expression)* ]
  3976. bool MasmParser::parseDirectiveNamedStructValue(const StructInfo &Structure,
  3977. StringRef Directive,
  3978. SMLoc DirLoc, StringRef Name) {
  3979. if (StructInProgress.empty()) {
  3980. // Initialize named data value.
  3981. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  3982. getStreamer().emitLabel(Sym);
  3983. unsigned Count;
  3984. if (emitStructValues(Structure, &Count))
  3985. return true;
  3986. AsmTypeInfo Type;
  3987. Type.Name = Structure.Name;
  3988. Type.Size = Structure.Size * Count;
  3989. Type.ElementSize = Structure.Size;
  3990. Type.Length = Count;
  3991. KnownType[Name.lower()] = Type;
  3992. } else if (addStructField(Name, Structure)) {
  3993. return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
  3994. }
  3995. return false;
  3996. }
  3997. /// parseDirectiveStruct
  3998. /// ::= <name> (STRUC | STRUCT | UNION) [fieldAlign] [, NONUNIQUE]
  3999. /// (dataDir | generalDir | offsetDir | nestedStruct)+
  4000. /// <name> ENDS
  4001. ////// dataDir = data declaration
  4002. ////// offsetDir = EVEN, ORG, ALIGN
  4003. bool MasmParser::parseDirectiveStruct(StringRef Directive,
  4004. DirectiveKind DirKind, StringRef Name,
  4005. SMLoc NameLoc) {
  4006. // We ignore NONUNIQUE; we do not support OPTION M510 or OPTION OLDSTRUCTS
  4007. // anyway, so all field accesses must be qualified.
  4008. AsmToken NextTok = getTok();
  4009. int64_t AlignmentValue = 1;
  4010. if (NextTok.isNot(AsmToken::Comma) &&
  4011. NextTok.isNot(AsmToken::EndOfStatement) &&
  4012. parseAbsoluteExpression(AlignmentValue)) {
  4013. return addErrorSuffix(" in alignment value for '" + Twine(Directive) +
  4014. "' directive");
  4015. }
  4016. if (!isPowerOf2_64(AlignmentValue)) {
  4017. return Error(NextTok.getLoc(), "alignment must be a power of two; was " +
  4018. std::to_string(AlignmentValue));
  4019. }
  4020. StringRef Qualifier;
  4021. SMLoc QualifierLoc;
  4022. if (parseOptionalToken(AsmToken::Comma)) {
  4023. QualifierLoc = getTok().getLoc();
  4024. if (parseIdentifier(Qualifier))
  4025. return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
  4026. if (!Qualifier.equals_insensitive("nonunique"))
  4027. return Error(QualifierLoc, "Unrecognized qualifier for '" +
  4028. Twine(Directive) +
  4029. "' directive; expected none or NONUNIQUE");
  4030. }
  4031. if (parseToken(AsmToken::EndOfStatement))
  4032. return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
  4033. StructInProgress.emplace_back(Name, DirKind == DK_UNION, AlignmentValue);
  4034. return false;
  4035. }
  4036. /// parseDirectiveNestedStruct
  4037. /// ::= (STRUC | STRUCT | UNION) [name]
  4038. /// (dataDir | generalDir | offsetDir | nestedStruct)+
  4039. /// ENDS
  4040. bool MasmParser::parseDirectiveNestedStruct(StringRef Directive,
  4041. DirectiveKind DirKind) {
  4042. if (StructInProgress.empty())
  4043. return TokError("missing name in top-level '" + Twine(Directive) +
  4044. "' directive");
  4045. StringRef Name;
  4046. if (getTok().is(AsmToken::Identifier)) {
  4047. Name = getTok().getIdentifier();
  4048. parseToken(AsmToken::Identifier);
  4049. }
  4050. if (parseToken(AsmToken::EndOfStatement))
  4051. return addErrorSuffix(" in '" + Twine(Directive) + "' directive");
  4052. // Reserve space to ensure Alignment doesn't get invalidated when
  4053. // StructInProgress grows.
  4054. StructInProgress.reserve(StructInProgress.size() + 1);
  4055. StructInProgress.emplace_back(Name, DirKind == DK_UNION,
  4056. StructInProgress.back().Alignment);
  4057. return false;
  4058. }
  4059. bool MasmParser::parseDirectiveEnds(StringRef Name, SMLoc NameLoc) {
  4060. if (StructInProgress.empty())
  4061. return Error(NameLoc, "ENDS directive without matching STRUC/STRUCT/UNION");
  4062. if (StructInProgress.size() > 1)
  4063. return Error(NameLoc, "unexpected name in nested ENDS directive");
  4064. if (StructInProgress.back().Name.compare_insensitive(Name))
  4065. return Error(NameLoc, "mismatched name in ENDS directive; expected '" +
  4066. StructInProgress.back().Name + "'");
  4067. StructInfo Structure = StructInProgress.pop_back_val();
  4068. // Pad to make the structure's size divisible by the smaller of its alignment
  4069. // and the size of its largest field.
  4070. Structure.Size = llvm::alignTo(
  4071. Structure.Size, std::min(Structure.Alignment, Structure.AlignmentSize));
  4072. Structs[Name.lower()] = Structure;
  4073. if (parseToken(AsmToken::EndOfStatement))
  4074. return addErrorSuffix(" in ENDS directive");
  4075. return false;
  4076. }
  4077. bool MasmParser::parseDirectiveNestedEnds() {
  4078. if (StructInProgress.empty())
  4079. return TokError("ENDS directive without matching STRUC/STRUCT/UNION");
  4080. if (StructInProgress.size() == 1)
  4081. return TokError("missing name in top-level ENDS directive");
  4082. if (parseToken(AsmToken::EndOfStatement))
  4083. return addErrorSuffix(" in nested ENDS directive");
  4084. StructInfo Structure = StructInProgress.pop_back_val();
  4085. // Pad to make the structure's size divisible by its alignment.
  4086. Structure.Size = llvm::alignTo(Structure.Size, Structure.Alignment);
  4087. StructInfo &ParentStruct = StructInProgress.back();
  4088. if (Structure.Name.empty()) {
  4089. // Anonymous substructures' fields are addressed as if they belong to the
  4090. // parent structure - so we transfer them to the parent here.
  4091. const size_t OldFields = ParentStruct.Fields.size();
  4092. ParentStruct.Fields.insert(
  4093. ParentStruct.Fields.end(),
  4094. std::make_move_iterator(Structure.Fields.begin()),
  4095. std::make_move_iterator(Structure.Fields.end()));
  4096. for (const auto &FieldByName : Structure.FieldsByName) {
  4097. ParentStruct.FieldsByName[FieldByName.getKey()] =
  4098. FieldByName.getValue() + OldFields;
  4099. }
  4100. unsigned FirstFieldOffset = 0;
  4101. if (!Structure.Fields.empty() && !ParentStruct.IsUnion) {
  4102. FirstFieldOffset = llvm::alignTo(
  4103. ParentStruct.NextOffset,
  4104. std::min(ParentStruct.Alignment, Structure.AlignmentSize));
  4105. }
  4106. if (ParentStruct.IsUnion) {
  4107. ParentStruct.Size = std::max(ParentStruct.Size, Structure.Size);
  4108. } else {
  4109. for (auto &Field : llvm::drop_begin(ParentStruct.Fields, OldFields))
  4110. Field.Offset += FirstFieldOffset;
  4111. const unsigned StructureEnd = FirstFieldOffset + Structure.Size;
  4112. if (!ParentStruct.IsUnion) {
  4113. ParentStruct.NextOffset = StructureEnd;
  4114. }
  4115. ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
  4116. }
  4117. } else {
  4118. FieldInfo &Field = ParentStruct.addField(Structure.Name, FT_STRUCT,
  4119. Structure.AlignmentSize);
  4120. StructFieldInfo &StructInfo = Field.Contents.StructInfo;
  4121. Field.Type = Structure.Size;
  4122. Field.LengthOf = 1;
  4123. Field.SizeOf = Structure.Size;
  4124. const unsigned StructureEnd = Field.Offset + Field.SizeOf;
  4125. if (!ParentStruct.IsUnion) {
  4126. ParentStruct.NextOffset = StructureEnd;
  4127. }
  4128. ParentStruct.Size = std::max(ParentStruct.Size, StructureEnd);
  4129. StructInfo.Structure = Structure;
  4130. StructInfo.Initializers.emplace_back();
  4131. auto &FieldInitializers = StructInfo.Initializers.back().FieldInitializers;
  4132. for (const auto &SubField : Structure.Fields) {
  4133. FieldInitializers.push_back(SubField.Contents);
  4134. }
  4135. }
  4136. return false;
  4137. }
  4138. /// parseDirectiveOrg
  4139. /// ::= org expression
  4140. bool MasmParser::parseDirectiveOrg() {
  4141. const MCExpr *Offset;
  4142. SMLoc OffsetLoc = Lexer.getLoc();
  4143. if (checkForValidSection() || parseExpression(Offset))
  4144. return true;
  4145. if (parseToken(AsmToken::EndOfStatement))
  4146. return addErrorSuffix(" in 'org' directive");
  4147. if (StructInProgress.empty()) {
  4148. // Not in a struct; change the offset for the next instruction or data
  4149. if (checkForValidSection())
  4150. return addErrorSuffix(" in 'org' directive");
  4151. getStreamer().emitValueToOffset(Offset, 0, OffsetLoc);
  4152. } else {
  4153. // Offset the next field of this struct
  4154. StructInfo &Structure = StructInProgress.back();
  4155. int64_t OffsetRes;
  4156. if (!Offset->evaluateAsAbsolute(OffsetRes, getStreamer().getAssemblerPtr()))
  4157. return Error(OffsetLoc,
  4158. "expected absolute expression in 'org' directive");
  4159. if (OffsetRes < 0)
  4160. return Error(
  4161. OffsetLoc,
  4162. "expected non-negative value in struct's 'org' directive; was " +
  4163. std::to_string(OffsetRes));
  4164. Structure.NextOffset = static_cast<unsigned>(OffsetRes);
  4165. // ORG-affected structures cannot be initialized
  4166. Structure.Initializable = false;
  4167. }
  4168. return false;
  4169. }
  4170. bool MasmParser::emitAlignTo(int64_t Alignment) {
  4171. if (StructInProgress.empty()) {
  4172. // Not in a struct; align the next instruction or data
  4173. if (checkForValidSection())
  4174. return true;
  4175. // Check whether we should use optimal code alignment for this align
  4176. // directive.
  4177. const MCSection *Section = getStreamer().getCurrentSectionOnly();
  4178. assert(Section && "must have section to emit alignment");
  4179. if (Section->useCodeAlign()) {
  4180. getStreamer().emitCodeAlignment(Align(Alignment),
  4181. &getTargetParser().getSTI(),
  4182. /*MaxBytesToEmit=*/0);
  4183. } else {
  4184. // FIXME: Target specific behavior about how the "extra" bytes are filled.
  4185. getStreamer().emitValueToAlignment(Align(Alignment), /*Value=*/0,
  4186. /*ValueSize=*/1,
  4187. /*MaxBytesToEmit=*/0);
  4188. }
  4189. } else {
  4190. // Align the next field of this struct
  4191. StructInfo &Structure = StructInProgress.back();
  4192. Structure.NextOffset = llvm::alignTo(Structure.NextOffset, Alignment);
  4193. }
  4194. return false;
  4195. }
  4196. /// parseDirectiveAlign
  4197. /// ::= align expression
  4198. bool MasmParser::parseDirectiveAlign() {
  4199. SMLoc AlignmentLoc = getLexer().getLoc();
  4200. int64_t Alignment;
  4201. // Ignore empty 'align' directives.
  4202. if (getTok().is(AsmToken::EndOfStatement)) {
  4203. return Warning(AlignmentLoc,
  4204. "align directive with no operand is ignored") &&
  4205. parseToken(AsmToken::EndOfStatement);
  4206. }
  4207. if (parseAbsoluteExpression(Alignment) ||
  4208. parseToken(AsmToken::EndOfStatement))
  4209. return addErrorSuffix(" in align directive");
  4210. // Always emit an alignment here even if we throw an error.
  4211. bool ReturnVal = false;
  4212. // Reject alignments that aren't either a power of two or zero, for ML.exe
  4213. // compatibility. Alignment of zero is silently rounded up to one.
  4214. if (Alignment == 0)
  4215. Alignment = 1;
  4216. if (!isPowerOf2_64(Alignment))
  4217. ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2; was " +
  4218. std::to_string(Alignment));
  4219. if (emitAlignTo(Alignment))
  4220. ReturnVal |= addErrorSuffix(" in align directive");
  4221. return ReturnVal;
  4222. }
  4223. /// parseDirectiveEven
  4224. /// ::= even
  4225. bool MasmParser::parseDirectiveEven() {
  4226. if (parseToken(AsmToken::EndOfStatement) || emitAlignTo(2))
  4227. return addErrorSuffix(" in even directive");
  4228. return false;
  4229. }
  4230. /// parseDirectiveFile
  4231. /// ::= .file filename
  4232. /// ::= .file number [directory] filename [md5 checksum] [source source-text]
  4233. bool MasmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
  4234. // FIXME: I'm not sure what this is.
  4235. int64_t FileNumber = -1;
  4236. if (getLexer().is(AsmToken::Integer)) {
  4237. FileNumber = getTok().getIntVal();
  4238. Lex();
  4239. if (FileNumber < 0)
  4240. return TokError("negative file number");
  4241. }
  4242. std::string Path;
  4243. // Usually the directory and filename together, otherwise just the directory.
  4244. // Allow the strings to have escaped octal character sequence.
  4245. if (check(getTok().isNot(AsmToken::String),
  4246. "unexpected token in '.file' directive") ||
  4247. parseEscapedString(Path))
  4248. return true;
  4249. StringRef Directory;
  4250. StringRef Filename;
  4251. std::string FilenameData;
  4252. if (getLexer().is(AsmToken::String)) {
  4253. if (check(FileNumber == -1,
  4254. "explicit path specified, but no file number") ||
  4255. parseEscapedString(FilenameData))
  4256. return true;
  4257. Filename = FilenameData;
  4258. Directory = Path;
  4259. } else {
  4260. Filename = Path;
  4261. }
  4262. uint64_t MD5Hi, MD5Lo;
  4263. bool HasMD5 = false;
  4264. std::optional<StringRef> Source;
  4265. bool HasSource = false;
  4266. std::string SourceString;
  4267. while (!parseOptionalToken(AsmToken::EndOfStatement)) {
  4268. StringRef Keyword;
  4269. if (check(getTok().isNot(AsmToken::Identifier),
  4270. "unexpected token in '.file' directive") ||
  4271. parseIdentifier(Keyword))
  4272. return true;
  4273. if (Keyword == "md5") {
  4274. HasMD5 = true;
  4275. if (check(FileNumber == -1,
  4276. "MD5 checksum specified, but no file number") ||
  4277. parseHexOcta(*this, MD5Hi, MD5Lo))
  4278. return true;
  4279. } else if (Keyword == "source") {
  4280. HasSource = true;
  4281. if (check(FileNumber == -1,
  4282. "source specified, but no file number") ||
  4283. check(getTok().isNot(AsmToken::String),
  4284. "unexpected token in '.file' directive") ||
  4285. parseEscapedString(SourceString))
  4286. return true;
  4287. } else {
  4288. return TokError("unexpected token in '.file' directive");
  4289. }
  4290. }
  4291. if (FileNumber == -1) {
  4292. // Ignore the directive if there is no number and the target doesn't support
  4293. // numberless .file directives. This allows some portability of assembler
  4294. // between different object file formats.
  4295. if (getContext().getAsmInfo()->hasSingleParameterDotFile())
  4296. getStreamer().emitFileDirective(Filename);
  4297. } else {
  4298. // In case there is a -g option as well as debug info from directive .file,
  4299. // we turn off the -g option, directly use the existing debug info instead.
  4300. // Throw away any implicit file table for the assembler source.
  4301. if (Ctx.getGenDwarfForAssembly()) {
  4302. Ctx.getMCDwarfLineTable(0).resetFileTable();
  4303. Ctx.setGenDwarfForAssembly(false);
  4304. }
  4305. std::optional<MD5::MD5Result> CKMem;
  4306. if (HasMD5) {
  4307. MD5::MD5Result Sum;
  4308. for (unsigned i = 0; i != 8; ++i) {
  4309. Sum[i] = uint8_t(MD5Hi >> ((7 - i) * 8));
  4310. Sum[i + 8] = uint8_t(MD5Lo >> ((7 - i) * 8));
  4311. }
  4312. CKMem = Sum;
  4313. }
  4314. if (HasSource) {
  4315. char *SourceBuf = static_cast<char *>(Ctx.allocate(SourceString.size()));
  4316. memcpy(SourceBuf, SourceString.data(), SourceString.size());
  4317. Source = StringRef(SourceBuf, SourceString.size());
  4318. }
  4319. if (FileNumber == 0) {
  4320. if (Ctx.getDwarfVersion() < 5)
  4321. return Warning(DirectiveLoc, "file 0 not supported prior to DWARF-5");
  4322. getStreamer().emitDwarfFile0Directive(Directory, Filename, CKMem, Source);
  4323. } else {
  4324. Expected<unsigned> FileNumOrErr = getStreamer().tryEmitDwarfFileDirective(
  4325. FileNumber, Directory, Filename, CKMem, Source);
  4326. if (!FileNumOrErr)
  4327. return Error(DirectiveLoc, toString(FileNumOrErr.takeError()));
  4328. }
  4329. // Alert the user if there are some .file directives with MD5 and some not.
  4330. // But only do that once.
  4331. if (!ReportedInconsistentMD5 && !Ctx.isDwarfMD5UsageConsistent(0)) {
  4332. ReportedInconsistentMD5 = true;
  4333. return Warning(DirectiveLoc, "inconsistent use of MD5 checksums");
  4334. }
  4335. }
  4336. return false;
  4337. }
  4338. /// parseDirectiveLine
  4339. /// ::= .line [number]
  4340. bool MasmParser::parseDirectiveLine() {
  4341. int64_t LineNumber;
  4342. if (getLexer().is(AsmToken::Integer)) {
  4343. if (parseIntToken(LineNumber, "unexpected token in '.line' directive"))
  4344. return true;
  4345. (void)LineNumber;
  4346. // FIXME: Do something with the .line.
  4347. }
  4348. if (parseEOL())
  4349. return true;
  4350. return false;
  4351. }
  4352. /// parseDirectiveLoc
  4353. /// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
  4354. /// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
  4355. /// The first number is a file number, must have been previously assigned with
  4356. /// a .file directive, the second number is the line number and optionally the
  4357. /// third number is a column position (zero if not specified). The remaining
  4358. /// optional items are .loc sub-directives.
  4359. bool MasmParser::parseDirectiveLoc() {
  4360. int64_t FileNumber = 0, LineNumber = 0;
  4361. SMLoc Loc = getTok().getLoc();
  4362. if (parseIntToken(FileNumber, "unexpected token in '.loc' directive") ||
  4363. check(FileNumber < 1 && Ctx.getDwarfVersion() < 5, Loc,
  4364. "file number less than one in '.loc' directive") ||
  4365. check(!getContext().isValidDwarfFileNumber(FileNumber), Loc,
  4366. "unassigned file number in '.loc' directive"))
  4367. return true;
  4368. // optional
  4369. if (getLexer().is(AsmToken::Integer)) {
  4370. LineNumber = getTok().getIntVal();
  4371. if (LineNumber < 0)
  4372. return TokError("line number less than zero in '.loc' directive");
  4373. Lex();
  4374. }
  4375. int64_t ColumnPos = 0;
  4376. if (getLexer().is(AsmToken::Integer)) {
  4377. ColumnPos = getTok().getIntVal();
  4378. if (ColumnPos < 0)
  4379. return TokError("column position less than zero in '.loc' directive");
  4380. Lex();
  4381. }
  4382. auto PrevFlags = getContext().getCurrentDwarfLoc().getFlags();
  4383. unsigned Flags = PrevFlags & DWARF2_FLAG_IS_STMT;
  4384. unsigned Isa = 0;
  4385. int64_t Discriminator = 0;
  4386. auto parseLocOp = [&]() -> bool {
  4387. StringRef Name;
  4388. SMLoc Loc = getTok().getLoc();
  4389. if (parseIdentifier(Name))
  4390. return TokError("unexpected token in '.loc' directive");
  4391. if (Name == "basic_block")
  4392. Flags |= DWARF2_FLAG_BASIC_BLOCK;
  4393. else if (Name == "prologue_end")
  4394. Flags |= DWARF2_FLAG_PROLOGUE_END;
  4395. else if (Name == "epilogue_begin")
  4396. Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
  4397. else if (Name == "is_stmt") {
  4398. Loc = getTok().getLoc();
  4399. const MCExpr *Value;
  4400. if (parseExpression(Value))
  4401. return true;
  4402. // The expression must be the constant 0 or 1.
  4403. if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
  4404. int Value = MCE->getValue();
  4405. if (Value == 0)
  4406. Flags &= ~DWARF2_FLAG_IS_STMT;
  4407. else if (Value == 1)
  4408. Flags |= DWARF2_FLAG_IS_STMT;
  4409. else
  4410. return Error(Loc, "is_stmt value not 0 or 1");
  4411. } else {
  4412. return Error(Loc, "is_stmt value not the constant value of 0 or 1");
  4413. }
  4414. } else if (Name == "isa") {
  4415. Loc = getTok().getLoc();
  4416. const MCExpr *Value;
  4417. if (parseExpression(Value))
  4418. return true;
  4419. // The expression must be a constant greater or equal to 0.
  4420. if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
  4421. int Value = MCE->getValue();
  4422. if (Value < 0)
  4423. return Error(Loc, "isa number less than zero");
  4424. Isa = Value;
  4425. } else {
  4426. return Error(Loc, "isa number not a constant value");
  4427. }
  4428. } else if (Name == "discriminator") {
  4429. if (parseAbsoluteExpression(Discriminator))
  4430. return true;
  4431. } else {
  4432. return Error(Loc, "unknown sub-directive in '.loc' directive");
  4433. }
  4434. return false;
  4435. };
  4436. if (parseMany(parseLocOp, false /*hasComma*/))
  4437. return true;
  4438. getStreamer().emitDwarfLocDirective(FileNumber, LineNumber, ColumnPos, Flags,
  4439. Isa, Discriminator, StringRef());
  4440. return false;
  4441. }
  4442. /// parseDirectiveStabs
  4443. /// ::= .stabs string, number, number, number
  4444. bool MasmParser::parseDirectiveStabs() {
  4445. return TokError("unsupported directive '.stabs'");
  4446. }
  4447. /// parseDirectiveCVFile
  4448. /// ::= .cv_file number filename [checksum] [checksumkind]
  4449. bool MasmParser::parseDirectiveCVFile() {
  4450. SMLoc FileNumberLoc = getTok().getLoc();
  4451. int64_t FileNumber;
  4452. std::string Filename;
  4453. std::string Checksum;
  4454. int64_t ChecksumKind = 0;
  4455. if (parseIntToken(FileNumber,
  4456. "expected file number in '.cv_file' directive") ||
  4457. check(FileNumber < 1, FileNumberLoc, "file number less than one") ||
  4458. check(getTok().isNot(AsmToken::String),
  4459. "unexpected token in '.cv_file' directive") ||
  4460. parseEscapedString(Filename))
  4461. return true;
  4462. if (!parseOptionalToken(AsmToken::EndOfStatement)) {
  4463. if (check(getTok().isNot(AsmToken::String),
  4464. "unexpected token in '.cv_file' directive") ||
  4465. parseEscapedString(Checksum) ||
  4466. parseIntToken(ChecksumKind,
  4467. "expected checksum kind in '.cv_file' directive") ||
  4468. parseEOL())
  4469. return true;
  4470. }
  4471. Checksum = fromHex(Checksum);
  4472. void *CKMem = Ctx.allocate(Checksum.size(), 1);
  4473. memcpy(CKMem, Checksum.data(), Checksum.size());
  4474. ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
  4475. Checksum.size());
  4476. if (!getStreamer().emitCVFileDirective(FileNumber, Filename, ChecksumAsBytes,
  4477. static_cast<uint8_t>(ChecksumKind)))
  4478. return Error(FileNumberLoc, "file number already allocated");
  4479. return false;
  4480. }
  4481. bool MasmParser::parseCVFunctionId(int64_t &FunctionId,
  4482. StringRef DirectiveName) {
  4483. SMLoc Loc;
  4484. return parseTokenLoc(Loc) ||
  4485. parseIntToken(FunctionId, "expected function id in '" + DirectiveName +
  4486. "' directive") ||
  4487. check(FunctionId < 0 || FunctionId >= UINT_MAX, Loc,
  4488. "expected function id within range [0, UINT_MAX)");
  4489. }
  4490. bool MasmParser::parseCVFileId(int64_t &FileNumber, StringRef DirectiveName) {
  4491. SMLoc Loc;
  4492. return parseTokenLoc(Loc) ||
  4493. parseIntToken(FileNumber, "expected integer in '" + DirectiveName +
  4494. "' directive") ||
  4495. check(FileNumber < 1, Loc, "file number less than one in '" +
  4496. DirectiveName + "' directive") ||
  4497. check(!getCVContext().isValidFileNumber(FileNumber), Loc,
  4498. "unassigned file number in '" + DirectiveName + "' directive");
  4499. }
  4500. /// parseDirectiveCVFuncId
  4501. /// ::= .cv_func_id FunctionId
  4502. ///
  4503. /// Introduces a function ID that can be used with .cv_loc.
  4504. bool MasmParser::parseDirectiveCVFuncId() {
  4505. SMLoc FunctionIdLoc = getTok().getLoc();
  4506. int64_t FunctionId;
  4507. if (parseCVFunctionId(FunctionId, ".cv_func_id") || parseEOL())
  4508. return true;
  4509. if (!getStreamer().emitCVFuncIdDirective(FunctionId))
  4510. return Error(FunctionIdLoc, "function id already allocated");
  4511. return false;
  4512. }
  4513. /// parseDirectiveCVInlineSiteId
  4514. /// ::= .cv_inline_site_id FunctionId
  4515. /// "within" IAFunc
  4516. /// "inlined_at" IAFile IALine [IACol]
  4517. ///
  4518. /// Introduces a function ID that can be used with .cv_loc. Includes "inlined
  4519. /// at" source location information for use in the line table of the caller,
  4520. /// whether the caller is a real function or another inlined call site.
  4521. bool MasmParser::parseDirectiveCVInlineSiteId() {
  4522. SMLoc FunctionIdLoc = getTok().getLoc();
  4523. int64_t FunctionId;
  4524. int64_t IAFunc;
  4525. int64_t IAFile;
  4526. int64_t IALine;
  4527. int64_t IACol = 0;
  4528. // FunctionId
  4529. if (parseCVFunctionId(FunctionId, ".cv_inline_site_id"))
  4530. return true;
  4531. // "within"
  4532. if (check((getLexer().isNot(AsmToken::Identifier) ||
  4533. getTok().getIdentifier() != "within"),
  4534. "expected 'within' identifier in '.cv_inline_site_id' directive"))
  4535. return true;
  4536. Lex();
  4537. // IAFunc
  4538. if (parseCVFunctionId(IAFunc, ".cv_inline_site_id"))
  4539. return true;
  4540. // "inlined_at"
  4541. if (check((getLexer().isNot(AsmToken::Identifier) ||
  4542. getTok().getIdentifier() != "inlined_at"),
  4543. "expected 'inlined_at' identifier in '.cv_inline_site_id' "
  4544. "directive") )
  4545. return true;
  4546. Lex();
  4547. // IAFile IALine
  4548. if (parseCVFileId(IAFile, ".cv_inline_site_id") ||
  4549. parseIntToken(IALine, "expected line number after 'inlined_at'"))
  4550. return true;
  4551. // [IACol]
  4552. if (getLexer().is(AsmToken::Integer)) {
  4553. IACol = getTok().getIntVal();
  4554. Lex();
  4555. }
  4556. if (parseEOL())
  4557. return true;
  4558. if (!getStreamer().emitCVInlineSiteIdDirective(FunctionId, IAFunc, IAFile,
  4559. IALine, IACol, FunctionIdLoc))
  4560. return Error(FunctionIdLoc, "function id already allocated");
  4561. return false;
  4562. }
  4563. /// parseDirectiveCVLoc
  4564. /// ::= .cv_loc FunctionId FileNumber [LineNumber] [ColumnPos] [prologue_end]
  4565. /// [is_stmt VALUE]
  4566. /// The first number is a file number, must have been previously assigned with
  4567. /// a .file directive, the second number is the line number and optionally the
  4568. /// third number is a column position (zero if not specified). The remaining
  4569. /// optional items are .loc sub-directives.
  4570. bool MasmParser::parseDirectiveCVLoc() {
  4571. SMLoc DirectiveLoc = getTok().getLoc();
  4572. int64_t FunctionId, FileNumber;
  4573. if (parseCVFunctionId(FunctionId, ".cv_loc") ||
  4574. parseCVFileId(FileNumber, ".cv_loc"))
  4575. return true;
  4576. int64_t LineNumber = 0;
  4577. if (getLexer().is(AsmToken::Integer)) {
  4578. LineNumber = getTok().getIntVal();
  4579. if (LineNumber < 0)
  4580. return TokError("line number less than zero in '.cv_loc' directive");
  4581. Lex();
  4582. }
  4583. int64_t ColumnPos = 0;
  4584. if (getLexer().is(AsmToken::Integer)) {
  4585. ColumnPos = getTok().getIntVal();
  4586. if (ColumnPos < 0)
  4587. return TokError("column position less than zero in '.cv_loc' directive");
  4588. Lex();
  4589. }
  4590. bool PrologueEnd = false;
  4591. uint64_t IsStmt = 0;
  4592. auto parseOp = [&]() -> bool {
  4593. StringRef Name;
  4594. SMLoc Loc = getTok().getLoc();
  4595. if (parseIdentifier(Name))
  4596. return TokError("unexpected token in '.cv_loc' directive");
  4597. if (Name == "prologue_end")
  4598. PrologueEnd = true;
  4599. else if (Name == "is_stmt") {
  4600. Loc = getTok().getLoc();
  4601. const MCExpr *Value;
  4602. if (parseExpression(Value))
  4603. return true;
  4604. // The expression must be the constant 0 or 1.
  4605. IsStmt = ~0ULL;
  4606. if (const auto *MCE = dyn_cast<MCConstantExpr>(Value))
  4607. IsStmt = MCE->getValue();
  4608. if (IsStmt > 1)
  4609. return Error(Loc, "is_stmt value not 0 or 1");
  4610. } else {
  4611. return Error(Loc, "unknown sub-directive in '.cv_loc' directive");
  4612. }
  4613. return false;
  4614. };
  4615. if (parseMany(parseOp, false /*hasComma*/))
  4616. return true;
  4617. getStreamer().emitCVLocDirective(FunctionId, FileNumber, LineNumber,
  4618. ColumnPos, PrologueEnd, IsStmt, StringRef(),
  4619. DirectiveLoc);
  4620. return false;
  4621. }
  4622. /// parseDirectiveCVLinetable
  4623. /// ::= .cv_linetable FunctionId, FnStart, FnEnd
  4624. bool MasmParser::parseDirectiveCVLinetable() {
  4625. int64_t FunctionId;
  4626. StringRef FnStartName, FnEndName;
  4627. SMLoc Loc = getTok().getLoc();
  4628. if (parseCVFunctionId(FunctionId, ".cv_linetable") ||
  4629. parseToken(AsmToken::Comma,
  4630. "unexpected token in '.cv_linetable' directive") ||
  4631. parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
  4632. "expected identifier in directive") ||
  4633. parseToken(AsmToken::Comma,
  4634. "unexpected token in '.cv_linetable' directive") ||
  4635. parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
  4636. "expected identifier in directive"))
  4637. return true;
  4638. MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
  4639. MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
  4640. getStreamer().emitCVLinetableDirective(FunctionId, FnStartSym, FnEndSym);
  4641. return false;
  4642. }
  4643. /// parseDirectiveCVInlineLinetable
  4644. /// ::= .cv_inline_linetable PrimaryFunctionId FileId LineNum FnStart FnEnd
  4645. bool MasmParser::parseDirectiveCVInlineLinetable() {
  4646. int64_t PrimaryFunctionId, SourceFileId, SourceLineNum;
  4647. StringRef FnStartName, FnEndName;
  4648. SMLoc Loc = getTok().getLoc();
  4649. if (parseCVFunctionId(PrimaryFunctionId, ".cv_inline_linetable") ||
  4650. parseTokenLoc(Loc) ||
  4651. parseIntToken(
  4652. SourceFileId,
  4653. "expected SourceField in '.cv_inline_linetable' directive") ||
  4654. check(SourceFileId <= 0, Loc,
  4655. "File id less than zero in '.cv_inline_linetable' directive") ||
  4656. parseTokenLoc(Loc) ||
  4657. parseIntToken(
  4658. SourceLineNum,
  4659. "expected SourceLineNum in '.cv_inline_linetable' directive") ||
  4660. check(SourceLineNum < 0, Loc,
  4661. "Line number less than zero in '.cv_inline_linetable' directive") ||
  4662. parseTokenLoc(Loc) || check(parseIdentifier(FnStartName), Loc,
  4663. "expected identifier in directive") ||
  4664. parseTokenLoc(Loc) || check(parseIdentifier(FnEndName), Loc,
  4665. "expected identifier in directive"))
  4666. return true;
  4667. if (parseEOL())
  4668. return true;
  4669. MCSymbol *FnStartSym = getContext().getOrCreateSymbol(FnStartName);
  4670. MCSymbol *FnEndSym = getContext().getOrCreateSymbol(FnEndName);
  4671. getStreamer().emitCVInlineLinetableDirective(PrimaryFunctionId, SourceFileId,
  4672. SourceLineNum, FnStartSym,
  4673. FnEndSym);
  4674. return false;
  4675. }
  4676. void MasmParser::initializeCVDefRangeTypeMap() {
  4677. CVDefRangeTypeMap["reg"] = CVDR_DEFRANGE_REGISTER;
  4678. CVDefRangeTypeMap["frame_ptr_rel"] = CVDR_DEFRANGE_FRAMEPOINTER_REL;
  4679. CVDefRangeTypeMap["subfield_reg"] = CVDR_DEFRANGE_SUBFIELD_REGISTER;
  4680. CVDefRangeTypeMap["reg_rel"] = CVDR_DEFRANGE_REGISTER_REL;
  4681. }
  4682. /// parseDirectiveCVDefRange
  4683. /// ::= .cv_def_range RangeStart RangeEnd (GapStart GapEnd)*, bytes*
  4684. bool MasmParser::parseDirectiveCVDefRange() {
  4685. SMLoc Loc;
  4686. std::vector<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
  4687. while (getLexer().is(AsmToken::Identifier)) {
  4688. Loc = getLexer().getLoc();
  4689. StringRef GapStartName;
  4690. if (parseIdentifier(GapStartName))
  4691. return Error(Loc, "expected identifier in directive");
  4692. MCSymbol *GapStartSym = getContext().getOrCreateSymbol(GapStartName);
  4693. Loc = getLexer().getLoc();
  4694. StringRef GapEndName;
  4695. if (parseIdentifier(GapEndName))
  4696. return Error(Loc, "expected identifier in directive");
  4697. MCSymbol *GapEndSym = getContext().getOrCreateSymbol(GapEndName);
  4698. Ranges.push_back({GapStartSym, GapEndSym});
  4699. }
  4700. StringRef CVDefRangeTypeStr;
  4701. if (parseToken(
  4702. AsmToken::Comma,
  4703. "expected comma before def_range type in .cv_def_range directive") ||
  4704. parseIdentifier(CVDefRangeTypeStr))
  4705. return Error(Loc, "expected def_range type in directive");
  4706. StringMap<CVDefRangeType>::const_iterator CVTypeIt =
  4707. CVDefRangeTypeMap.find(CVDefRangeTypeStr);
  4708. CVDefRangeType CVDRType = (CVTypeIt == CVDefRangeTypeMap.end())
  4709. ? CVDR_DEFRANGE
  4710. : CVTypeIt->getValue();
  4711. switch (CVDRType) {
  4712. case CVDR_DEFRANGE_REGISTER: {
  4713. int64_t DRRegister;
  4714. if (parseToken(AsmToken::Comma, "expected comma before register number in "
  4715. ".cv_def_range directive") ||
  4716. parseAbsoluteExpression(DRRegister))
  4717. return Error(Loc, "expected register number");
  4718. codeview::DefRangeRegisterHeader DRHdr;
  4719. DRHdr.Register = DRRegister;
  4720. DRHdr.MayHaveNoName = 0;
  4721. getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
  4722. break;
  4723. }
  4724. case CVDR_DEFRANGE_FRAMEPOINTER_REL: {
  4725. int64_t DROffset;
  4726. if (parseToken(AsmToken::Comma,
  4727. "expected comma before offset in .cv_def_range directive") ||
  4728. parseAbsoluteExpression(DROffset))
  4729. return Error(Loc, "expected offset value");
  4730. codeview::DefRangeFramePointerRelHeader DRHdr;
  4731. DRHdr.Offset = DROffset;
  4732. getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
  4733. break;
  4734. }
  4735. case CVDR_DEFRANGE_SUBFIELD_REGISTER: {
  4736. int64_t DRRegister;
  4737. int64_t DROffsetInParent;
  4738. if (parseToken(AsmToken::Comma, "expected comma before register number in "
  4739. ".cv_def_range directive") ||
  4740. parseAbsoluteExpression(DRRegister))
  4741. return Error(Loc, "expected register number");
  4742. if (parseToken(AsmToken::Comma,
  4743. "expected comma before offset in .cv_def_range directive") ||
  4744. parseAbsoluteExpression(DROffsetInParent))
  4745. return Error(Loc, "expected offset value");
  4746. codeview::DefRangeSubfieldRegisterHeader DRHdr;
  4747. DRHdr.Register = DRRegister;
  4748. DRHdr.MayHaveNoName = 0;
  4749. DRHdr.OffsetInParent = DROffsetInParent;
  4750. getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
  4751. break;
  4752. }
  4753. case CVDR_DEFRANGE_REGISTER_REL: {
  4754. int64_t DRRegister;
  4755. int64_t DRFlags;
  4756. int64_t DRBasePointerOffset;
  4757. if (parseToken(AsmToken::Comma, "expected comma before register number in "
  4758. ".cv_def_range directive") ||
  4759. parseAbsoluteExpression(DRRegister))
  4760. return Error(Loc, "expected register value");
  4761. if (parseToken(
  4762. AsmToken::Comma,
  4763. "expected comma before flag value in .cv_def_range directive") ||
  4764. parseAbsoluteExpression(DRFlags))
  4765. return Error(Loc, "expected flag value");
  4766. if (parseToken(AsmToken::Comma, "expected comma before base pointer offset "
  4767. "in .cv_def_range directive") ||
  4768. parseAbsoluteExpression(DRBasePointerOffset))
  4769. return Error(Loc, "expected base pointer offset value");
  4770. codeview::DefRangeRegisterRelHeader DRHdr;
  4771. DRHdr.Register = DRRegister;
  4772. DRHdr.Flags = DRFlags;
  4773. DRHdr.BasePointerOffset = DRBasePointerOffset;
  4774. getStreamer().emitCVDefRangeDirective(Ranges, DRHdr);
  4775. break;
  4776. }
  4777. default:
  4778. return Error(Loc, "unexpected def_range type in .cv_def_range directive");
  4779. }
  4780. return true;
  4781. }
  4782. /// parseDirectiveCVString
  4783. /// ::= .cv_stringtable "string"
  4784. bool MasmParser::parseDirectiveCVString() {
  4785. std::string Data;
  4786. if (checkForValidSection() || parseEscapedString(Data))
  4787. return addErrorSuffix(" in '.cv_string' directive");
  4788. // Put the string in the table and emit the offset.
  4789. std::pair<StringRef, unsigned> Insertion =
  4790. getCVContext().addToStringTable(Data);
  4791. getStreamer().emitIntValue(Insertion.second, 4);
  4792. return false;
  4793. }
  4794. /// parseDirectiveCVStringTable
  4795. /// ::= .cv_stringtable
  4796. bool MasmParser::parseDirectiveCVStringTable() {
  4797. getStreamer().emitCVStringTableDirective();
  4798. return false;
  4799. }
  4800. /// parseDirectiveCVFileChecksums
  4801. /// ::= .cv_filechecksums
  4802. bool MasmParser::parseDirectiveCVFileChecksums() {
  4803. getStreamer().emitCVFileChecksumsDirective();
  4804. return false;
  4805. }
  4806. /// parseDirectiveCVFileChecksumOffset
  4807. /// ::= .cv_filechecksumoffset fileno
  4808. bool MasmParser::parseDirectiveCVFileChecksumOffset() {
  4809. int64_t FileNo;
  4810. if (parseIntToken(FileNo, "expected identifier in directive"))
  4811. return true;
  4812. if (parseEOL())
  4813. return true;
  4814. getStreamer().emitCVFileChecksumOffsetDirective(FileNo);
  4815. return false;
  4816. }
  4817. /// parseDirectiveCVFPOData
  4818. /// ::= .cv_fpo_data procsym
  4819. bool MasmParser::parseDirectiveCVFPOData() {
  4820. SMLoc DirLoc = getLexer().getLoc();
  4821. StringRef ProcName;
  4822. if (parseIdentifier(ProcName))
  4823. return TokError("expected symbol name");
  4824. if (parseEOL("unexpected tokens"))
  4825. return addErrorSuffix(" in '.cv_fpo_data' directive");
  4826. MCSymbol *ProcSym = getContext().getOrCreateSymbol(ProcName);
  4827. getStreamer().emitCVFPOData(ProcSym, DirLoc);
  4828. return false;
  4829. }
  4830. /// parseDirectiveCFISections
  4831. /// ::= .cfi_sections section [, section]
  4832. bool MasmParser::parseDirectiveCFISections() {
  4833. StringRef Name;
  4834. bool EH = false;
  4835. bool Debug = false;
  4836. if (parseIdentifier(Name))
  4837. return TokError("Expected an identifier");
  4838. if (Name == ".eh_frame")
  4839. EH = true;
  4840. else if (Name == ".debug_frame")
  4841. Debug = true;
  4842. if (getLexer().is(AsmToken::Comma)) {
  4843. Lex();
  4844. if (parseIdentifier(Name))
  4845. return TokError("Expected an identifier");
  4846. if (Name == ".eh_frame")
  4847. EH = true;
  4848. else if (Name == ".debug_frame")
  4849. Debug = true;
  4850. }
  4851. getStreamer().emitCFISections(EH, Debug);
  4852. return false;
  4853. }
  4854. /// parseDirectiveCFIStartProc
  4855. /// ::= .cfi_startproc [simple]
  4856. bool MasmParser::parseDirectiveCFIStartProc() {
  4857. StringRef Simple;
  4858. if (!parseOptionalToken(AsmToken::EndOfStatement)) {
  4859. if (check(parseIdentifier(Simple) || Simple != "simple",
  4860. "unexpected token") ||
  4861. parseToken(AsmToken::EndOfStatement))
  4862. return addErrorSuffix(" in '.cfi_startproc' directive");
  4863. }
  4864. // TODO(kristina): Deal with a corner case of incorrect diagnostic context
  4865. // being produced if this directive is emitted as part of preprocessor macro
  4866. // expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
  4867. // Tools like llvm-mc on the other hand are not affected by it, and report
  4868. // correct context information.
  4869. getStreamer().emitCFIStartProc(!Simple.empty(), Lexer.getLoc());
  4870. return false;
  4871. }
  4872. /// parseDirectiveCFIEndProc
  4873. /// ::= .cfi_endproc
  4874. bool MasmParser::parseDirectiveCFIEndProc() {
  4875. getStreamer().emitCFIEndProc();
  4876. return false;
  4877. }
  4878. /// parse register name or number.
  4879. bool MasmParser::parseRegisterOrRegisterNumber(int64_t &Register,
  4880. SMLoc DirectiveLoc) {
  4881. MCRegister RegNo;
  4882. if (getLexer().isNot(AsmToken::Integer)) {
  4883. if (getTargetParser().parseRegister(RegNo, DirectiveLoc, DirectiveLoc))
  4884. return true;
  4885. Register = getContext().getRegisterInfo()->getDwarfRegNum(RegNo, true);
  4886. } else
  4887. return parseAbsoluteExpression(Register);
  4888. return false;
  4889. }
  4890. /// parseDirectiveCFIDefCfa
  4891. /// ::= .cfi_def_cfa register, offset
  4892. bool MasmParser::parseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
  4893. int64_t Register = 0, Offset = 0;
  4894. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
  4895. parseToken(AsmToken::Comma, "unexpected token in directive") ||
  4896. parseAbsoluteExpression(Offset))
  4897. return true;
  4898. getStreamer().emitCFIDefCfa(Register, Offset);
  4899. return false;
  4900. }
  4901. /// parseDirectiveCFIDefCfaOffset
  4902. /// ::= .cfi_def_cfa_offset offset
  4903. bool MasmParser::parseDirectiveCFIDefCfaOffset() {
  4904. int64_t Offset = 0;
  4905. if (parseAbsoluteExpression(Offset))
  4906. return true;
  4907. getStreamer().emitCFIDefCfaOffset(Offset);
  4908. return false;
  4909. }
  4910. /// parseDirectiveCFIRegister
  4911. /// ::= .cfi_register register, register
  4912. bool MasmParser::parseDirectiveCFIRegister(SMLoc DirectiveLoc) {
  4913. int64_t Register1 = 0, Register2 = 0;
  4914. if (parseRegisterOrRegisterNumber(Register1, DirectiveLoc) ||
  4915. parseToken(AsmToken::Comma, "unexpected token in directive") ||
  4916. parseRegisterOrRegisterNumber(Register2, DirectiveLoc))
  4917. return true;
  4918. getStreamer().emitCFIRegister(Register1, Register2);
  4919. return false;
  4920. }
  4921. /// parseDirectiveCFIWindowSave
  4922. /// ::= .cfi_window_save
  4923. bool MasmParser::parseDirectiveCFIWindowSave() {
  4924. getStreamer().emitCFIWindowSave();
  4925. return false;
  4926. }
  4927. /// parseDirectiveCFIAdjustCfaOffset
  4928. /// ::= .cfi_adjust_cfa_offset adjustment
  4929. bool MasmParser::parseDirectiveCFIAdjustCfaOffset() {
  4930. int64_t Adjustment = 0;
  4931. if (parseAbsoluteExpression(Adjustment))
  4932. return true;
  4933. getStreamer().emitCFIAdjustCfaOffset(Adjustment);
  4934. return false;
  4935. }
  4936. /// parseDirectiveCFIDefCfaRegister
  4937. /// ::= .cfi_def_cfa_register register
  4938. bool MasmParser::parseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
  4939. int64_t Register = 0;
  4940. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
  4941. return true;
  4942. getStreamer().emitCFIDefCfaRegister(Register);
  4943. return false;
  4944. }
  4945. /// parseDirectiveCFIOffset
  4946. /// ::= .cfi_offset register, offset
  4947. bool MasmParser::parseDirectiveCFIOffset(SMLoc DirectiveLoc) {
  4948. int64_t Register = 0;
  4949. int64_t Offset = 0;
  4950. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
  4951. parseToken(AsmToken::Comma, "unexpected token in directive") ||
  4952. parseAbsoluteExpression(Offset))
  4953. return true;
  4954. getStreamer().emitCFIOffset(Register, Offset);
  4955. return false;
  4956. }
  4957. /// parseDirectiveCFIRelOffset
  4958. /// ::= .cfi_rel_offset register, offset
  4959. bool MasmParser::parseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
  4960. int64_t Register = 0, Offset = 0;
  4961. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc) ||
  4962. parseToken(AsmToken::Comma, "unexpected token in directive") ||
  4963. parseAbsoluteExpression(Offset))
  4964. return true;
  4965. getStreamer().emitCFIRelOffset(Register, Offset);
  4966. return false;
  4967. }
  4968. static bool isValidEncoding(int64_t Encoding) {
  4969. if (Encoding & ~0xff)
  4970. return false;
  4971. if (Encoding == dwarf::DW_EH_PE_omit)
  4972. return true;
  4973. const unsigned Format = Encoding & 0xf;
  4974. if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
  4975. Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
  4976. Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
  4977. Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
  4978. return false;
  4979. const unsigned Application = Encoding & 0x70;
  4980. if (Application != dwarf::DW_EH_PE_absptr &&
  4981. Application != dwarf::DW_EH_PE_pcrel)
  4982. return false;
  4983. return true;
  4984. }
  4985. /// parseDirectiveCFIPersonalityOrLsda
  4986. /// IsPersonality true for cfi_personality, false for cfi_lsda
  4987. /// ::= .cfi_personality encoding, [symbol_name]
  4988. /// ::= .cfi_lsda encoding, [symbol_name]
  4989. bool MasmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
  4990. int64_t Encoding = 0;
  4991. if (parseAbsoluteExpression(Encoding))
  4992. return true;
  4993. if (Encoding == dwarf::DW_EH_PE_omit)
  4994. return false;
  4995. StringRef Name;
  4996. if (check(!isValidEncoding(Encoding), "unsupported encoding.") ||
  4997. parseToken(AsmToken::Comma, "unexpected token in directive") ||
  4998. check(parseIdentifier(Name), "expected identifier in directive"))
  4999. return true;
  5000. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  5001. if (IsPersonality)
  5002. getStreamer().emitCFIPersonality(Sym, Encoding);
  5003. else
  5004. getStreamer().emitCFILsda(Sym, Encoding);
  5005. return false;
  5006. }
  5007. /// parseDirectiveCFIRememberState
  5008. /// ::= .cfi_remember_state
  5009. bool MasmParser::parseDirectiveCFIRememberState() {
  5010. getStreamer().emitCFIRememberState();
  5011. return false;
  5012. }
  5013. /// parseDirectiveCFIRestoreState
  5014. /// ::= .cfi_remember_state
  5015. bool MasmParser::parseDirectiveCFIRestoreState() {
  5016. getStreamer().emitCFIRestoreState();
  5017. return false;
  5018. }
  5019. /// parseDirectiveCFISameValue
  5020. /// ::= .cfi_same_value register
  5021. bool MasmParser::parseDirectiveCFISameValue(SMLoc DirectiveLoc) {
  5022. int64_t Register = 0;
  5023. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
  5024. return true;
  5025. getStreamer().emitCFISameValue(Register);
  5026. return false;
  5027. }
  5028. /// parseDirectiveCFIRestore
  5029. /// ::= .cfi_restore register
  5030. bool MasmParser::parseDirectiveCFIRestore(SMLoc DirectiveLoc) {
  5031. int64_t Register = 0;
  5032. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
  5033. return true;
  5034. getStreamer().emitCFIRestore(Register);
  5035. return false;
  5036. }
  5037. /// parseDirectiveCFIEscape
  5038. /// ::= .cfi_escape expression[,...]
  5039. bool MasmParser::parseDirectiveCFIEscape() {
  5040. std::string Values;
  5041. int64_t CurrValue;
  5042. if (parseAbsoluteExpression(CurrValue))
  5043. return true;
  5044. Values.push_back((uint8_t)CurrValue);
  5045. while (getLexer().is(AsmToken::Comma)) {
  5046. Lex();
  5047. if (parseAbsoluteExpression(CurrValue))
  5048. return true;
  5049. Values.push_back((uint8_t)CurrValue);
  5050. }
  5051. getStreamer().emitCFIEscape(Values);
  5052. return false;
  5053. }
  5054. /// parseDirectiveCFIReturnColumn
  5055. /// ::= .cfi_return_column register
  5056. bool MasmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
  5057. int64_t Register = 0;
  5058. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
  5059. return true;
  5060. getStreamer().emitCFIReturnColumn(Register);
  5061. return false;
  5062. }
  5063. /// parseDirectiveCFISignalFrame
  5064. /// ::= .cfi_signal_frame
  5065. bool MasmParser::parseDirectiveCFISignalFrame() {
  5066. if (parseEOL())
  5067. return true;
  5068. getStreamer().emitCFISignalFrame();
  5069. return false;
  5070. }
  5071. /// parseDirectiveCFIUndefined
  5072. /// ::= .cfi_undefined register
  5073. bool MasmParser::parseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
  5074. int64_t Register = 0;
  5075. if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
  5076. return true;
  5077. getStreamer().emitCFIUndefined(Register);
  5078. return false;
  5079. }
  5080. /// parseDirectiveMacro
  5081. /// ::= name macro [parameters]
  5082. /// ["LOCAL" identifiers]
  5083. /// parameters ::= parameter [, parameter]*
  5084. /// parameter ::= name ":" qualifier
  5085. /// qualifier ::= "req" | "vararg" | "=" macro_argument
  5086. bool MasmParser::parseDirectiveMacro(StringRef Name, SMLoc NameLoc) {
  5087. MCAsmMacroParameters Parameters;
  5088. while (getLexer().isNot(AsmToken::EndOfStatement)) {
  5089. if (!Parameters.empty() && Parameters.back().Vararg)
  5090. return Error(Lexer.getLoc(),
  5091. "Vararg parameter '" + Parameters.back().Name +
  5092. "' should be last in the list of parameters");
  5093. MCAsmMacroParameter Parameter;
  5094. if (parseIdentifier(Parameter.Name))
  5095. return TokError("expected identifier in 'macro' directive");
  5096. // Emit an error if two (or more) named parameters share the same name.
  5097. for (const MCAsmMacroParameter& CurrParam : Parameters)
  5098. if (CurrParam.Name.equals_insensitive(Parameter.Name))
  5099. return TokError("macro '" + Name + "' has multiple parameters"
  5100. " named '" + Parameter.Name + "'");
  5101. if (Lexer.is(AsmToken::Colon)) {
  5102. Lex(); // consume ':'
  5103. if (parseOptionalToken(AsmToken::Equal)) {
  5104. // Default value
  5105. SMLoc ParamLoc;
  5106. ParamLoc = Lexer.getLoc();
  5107. if (parseMacroArgument(nullptr, Parameter.Value))
  5108. return true;
  5109. } else {
  5110. SMLoc QualLoc;
  5111. StringRef Qualifier;
  5112. QualLoc = Lexer.getLoc();
  5113. if (parseIdentifier(Qualifier))
  5114. return Error(QualLoc, "missing parameter qualifier for "
  5115. "'" +
  5116. Parameter.Name + "' in macro '" + Name +
  5117. "'");
  5118. if (Qualifier.equals_insensitive("req"))
  5119. Parameter.Required = true;
  5120. else if (Qualifier.equals_insensitive("vararg"))
  5121. Parameter.Vararg = true;
  5122. else
  5123. return Error(QualLoc,
  5124. Qualifier + " is not a valid parameter qualifier for '" +
  5125. Parameter.Name + "' in macro '" + Name + "'");
  5126. }
  5127. }
  5128. Parameters.push_back(std::move(Parameter));
  5129. if (getLexer().is(AsmToken::Comma))
  5130. Lex();
  5131. }
  5132. // Eat just the end of statement.
  5133. Lexer.Lex();
  5134. std::vector<std::string> Locals;
  5135. if (getTok().is(AsmToken::Identifier) &&
  5136. getTok().getIdentifier().equals_insensitive("local")) {
  5137. Lex(); // Eat the LOCAL directive.
  5138. StringRef ID;
  5139. while (true) {
  5140. if (parseIdentifier(ID))
  5141. return true;
  5142. Locals.push_back(ID.lower());
  5143. // If we see a comma, continue (and allow line continuation).
  5144. if (!parseOptionalToken(AsmToken::Comma))
  5145. break;
  5146. parseOptionalToken(AsmToken::EndOfStatement);
  5147. }
  5148. }
  5149. // Consuming deferred text, so use Lexer.Lex to ignore Lexing Errors.
  5150. AsmToken EndToken, StartToken = getTok();
  5151. unsigned MacroDepth = 0;
  5152. bool IsMacroFunction = false;
  5153. // Lex the macro definition.
  5154. while (true) {
  5155. // Ignore Lexing errors in macros.
  5156. while (Lexer.is(AsmToken::Error)) {
  5157. Lexer.Lex();
  5158. }
  5159. // Check whether we have reached the end of the file.
  5160. if (getLexer().is(AsmToken::Eof))
  5161. return Error(NameLoc, "no matching 'endm' in definition");
  5162. // Otherwise, check whether we have reached the 'endm'... and determine if
  5163. // this is a macro function.
  5164. if (getLexer().is(AsmToken::Identifier)) {
  5165. if (getTok().getIdentifier().equals_insensitive("endm")) {
  5166. if (MacroDepth == 0) { // Outermost macro.
  5167. EndToken = getTok();
  5168. Lexer.Lex();
  5169. if (getLexer().isNot(AsmToken::EndOfStatement))
  5170. return TokError("unexpected token in '" + EndToken.getIdentifier() +
  5171. "' directive");
  5172. break;
  5173. } else {
  5174. // Otherwise we just found the end of an inner macro.
  5175. --MacroDepth;
  5176. }
  5177. } else if (getTok().getIdentifier().equals_insensitive("exitm")) {
  5178. if (MacroDepth == 0 && peekTok().isNot(AsmToken::EndOfStatement)) {
  5179. IsMacroFunction = true;
  5180. }
  5181. } else if (isMacroLikeDirective()) {
  5182. // We allow nested macros. Those aren't instantiated until the
  5183. // outermost macro is expanded so just ignore them for now.
  5184. ++MacroDepth;
  5185. }
  5186. }
  5187. // Otherwise, scan til the end of the statement.
  5188. eatToEndOfStatement();
  5189. }
  5190. if (getContext().lookupMacro(Name.lower())) {
  5191. return Error(NameLoc, "macro '" + Name + "' is already defined");
  5192. }
  5193. const char *BodyStart = StartToken.getLoc().getPointer();
  5194. const char *BodyEnd = EndToken.getLoc().getPointer();
  5195. StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
  5196. MCAsmMacro Macro(Name, Body, std::move(Parameters), std::move(Locals),
  5197. IsMacroFunction);
  5198. DEBUG_WITH_TYPE("asm-macros", dbgs() << "Defining new macro:\n";
  5199. Macro.dump());
  5200. getContext().defineMacro(Name.lower(), std::move(Macro));
  5201. return false;
  5202. }
  5203. /// parseDirectiveExitMacro
  5204. /// ::= "exitm" [textitem]
  5205. bool MasmParser::parseDirectiveExitMacro(SMLoc DirectiveLoc,
  5206. StringRef Directive,
  5207. std::string &Value) {
  5208. SMLoc EndLoc = getTok().getLoc();
  5209. if (getTok().isNot(AsmToken::EndOfStatement) && parseTextItem(Value))
  5210. return Error(EndLoc,
  5211. "unable to parse text item in '" + Directive + "' directive");
  5212. eatToEndOfStatement();
  5213. if (!isInsideMacroInstantiation())
  5214. return TokError("unexpected '" + Directive + "' in file, "
  5215. "no current macro definition");
  5216. // Exit all conditionals that are active in the current macro.
  5217. while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
  5218. TheCondState = TheCondStack.back();
  5219. TheCondStack.pop_back();
  5220. }
  5221. handleMacroExit();
  5222. return false;
  5223. }
  5224. /// parseDirectiveEndMacro
  5225. /// ::= endm
  5226. bool MasmParser::parseDirectiveEndMacro(StringRef Directive) {
  5227. if (getLexer().isNot(AsmToken::EndOfStatement))
  5228. return TokError("unexpected token in '" + Directive + "' directive");
  5229. // If we are inside a macro instantiation, terminate the current
  5230. // instantiation.
  5231. if (isInsideMacroInstantiation()) {
  5232. handleMacroExit();
  5233. return false;
  5234. }
  5235. // Otherwise, this .endmacro is a stray entry in the file; well formed
  5236. // .endmacro directives are handled during the macro definition parsing.
  5237. return TokError("unexpected '" + Directive + "' in file, "
  5238. "no current macro definition");
  5239. }
  5240. /// parseDirectivePurgeMacro
  5241. /// ::= purge identifier ( , identifier )*
  5242. bool MasmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
  5243. StringRef Name;
  5244. while (true) {
  5245. SMLoc NameLoc;
  5246. if (parseTokenLoc(NameLoc) ||
  5247. check(parseIdentifier(Name), NameLoc,
  5248. "expected identifier in 'purge' directive"))
  5249. return true;
  5250. DEBUG_WITH_TYPE("asm-macros", dbgs()
  5251. << "Un-defining macro: " << Name << "\n");
  5252. if (!getContext().lookupMacro(Name.lower()))
  5253. return Error(NameLoc, "macro '" + Name + "' is not defined");
  5254. getContext().undefineMacro(Name.lower());
  5255. if (!parseOptionalToken(AsmToken::Comma))
  5256. break;
  5257. parseOptionalToken(AsmToken::EndOfStatement);
  5258. }
  5259. return false;
  5260. }
  5261. bool MasmParser::parseDirectiveExtern() {
  5262. // .extern is the default - but we still need to take any provided type info.
  5263. auto parseOp = [&]() -> bool {
  5264. StringRef Name;
  5265. SMLoc NameLoc = getTok().getLoc();
  5266. if (parseIdentifier(Name))
  5267. return Error(NameLoc, "expected name");
  5268. if (parseToken(AsmToken::Colon))
  5269. return true;
  5270. StringRef TypeName;
  5271. SMLoc TypeLoc = getTok().getLoc();
  5272. if (parseIdentifier(TypeName))
  5273. return Error(TypeLoc, "expected type");
  5274. if (!TypeName.equals_insensitive("proc")) {
  5275. AsmTypeInfo Type;
  5276. if (lookUpType(TypeName, Type))
  5277. return Error(TypeLoc, "unrecognized type");
  5278. KnownType[Name.lower()] = Type;
  5279. }
  5280. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  5281. Sym->setExternal(true);
  5282. getStreamer().emitSymbolAttribute(Sym, MCSA_Extern);
  5283. return false;
  5284. };
  5285. if (parseMany(parseOp))
  5286. return addErrorSuffix(" in directive 'extern'");
  5287. return false;
  5288. }
  5289. /// parseDirectiveSymbolAttribute
  5290. /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
  5291. bool MasmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
  5292. auto parseOp = [&]() -> bool {
  5293. StringRef Name;
  5294. SMLoc Loc = getTok().getLoc();
  5295. if (parseIdentifier(Name))
  5296. return Error(Loc, "expected identifier");
  5297. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  5298. // Assembler local symbols don't make any sense here. Complain loudly.
  5299. if (Sym->isTemporary())
  5300. return Error(Loc, "non-local symbol required");
  5301. if (!getStreamer().emitSymbolAttribute(Sym, Attr))
  5302. return Error(Loc, "unable to emit symbol attribute");
  5303. return false;
  5304. };
  5305. if (parseMany(parseOp))
  5306. return addErrorSuffix(" in directive");
  5307. return false;
  5308. }
  5309. /// parseDirectiveComm
  5310. /// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
  5311. bool MasmParser::parseDirectiveComm(bool IsLocal) {
  5312. if (checkForValidSection())
  5313. return true;
  5314. SMLoc IDLoc = getLexer().getLoc();
  5315. StringRef Name;
  5316. if (parseIdentifier(Name))
  5317. return TokError("expected identifier in directive");
  5318. // Handle the identifier as the key symbol.
  5319. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  5320. if (getLexer().isNot(AsmToken::Comma))
  5321. return TokError("unexpected token in directive");
  5322. Lex();
  5323. int64_t Size;
  5324. SMLoc SizeLoc = getLexer().getLoc();
  5325. if (parseAbsoluteExpression(Size))
  5326. return true;
  5327. int64_t Pow2Alignment = 0;
  5328. SMLoc Pow2AlignmentLoc;
  5329. if (getLexer().is(AsmToken::Comma)) {
  5330. Lex();
  5331. Pow2AlignmentLoc = getLexer().getLoc();
  5332. if (parseAbsoluteExpression(Pow2Alignment))
  5333. return true;
  5334. LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
  5335. if (IsLocal && LCOMM == LCOMM::NoAlignment)
  5336. return Error(Pow2AlignmentLoc, "alignment not supported on this target");
  5337. // If this target takes alignments in bytes (not log) validate and convert.
  5338. if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
  5339. (IsLocal && LCOMM == LCOMM::ByteAlignment)) {
  5340. if (!isPowerOf2_64(Pow2Alignment))
  5341. return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
  5342. Pow2Alignment = Log2_64(Pow2Alignment);
  5343. }
  5344. }
  5345. if (parseEOL())
  5346. return true;
  5347. // NOTE: a size of zero for a .comm should create a undefined symbol
  5348. // but a size of .lcomm creates a bss symbol of size zero.
  5349. if (Size < 0)
  5350. return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
  5351. "be less than zero");
  5352. // NOTE: The alignment in the directive is a power of 2 value, the assembler
  5353. // may internally end up wanting an alignment in bytes.
  5354. // FIXME: Diagnose overflow.
  5355. if (Pow2Alignment < 0)
  5356. return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
  5357. "alignment, can't be less than zero");
  5358. Sym->redefineIfPossible();
  5359. if (!Sym->isUndefined())
  5360. return Error(IDLoc, "invalid symbol redefinition");
  5361. // Create the Symbol as a common or local common with Size and Pow2Alignment.
  5362. if (IsLocal) {
  5363. getStreamer().emitLocalCommonSymbol(Sym, Size,
  5364. Align(1ULL << Pow2Alignment));
  5365. return false;
  5366. }
  5367. getStreamer().emitCommonSymbol(Sym, Size, Align(1ULL << Pow2Alignment));
  5368. return false;
  5369. }
  5370. /// parseDirectiveComment
  5371. /// ::= comment delimiter [[text]]
  5372. /// [[text]]
  5373. /// [[text]] delimiter [[text]]
  5374. bool MasmParser::parseDirectiveComment(SMLoc DirectiveLoc) {
  5375. std::string FirstLine = parseStringTo(AsmToken::EndOfStatement);
  5376. size_t DelimiterEnd = FirstLine.find_first_of("\b\t\v\f\r\x1A ");
  5377. StringRef Delimiter = StringRef(FirstLine).take_front(DelimiterEnd);
  5378. if (Delimiter.empty())
  5379. return Error(DirectiveLoc, "no delimiter in 'comment' directive");
  5380. do {
  5381. if (getTok().is(AsmToken::Eof))
  5382. return Error(DirectiveLoc, "unmatched delimiter in 'comment' directive");
  5383. Lex(); // eat end of statement
  5384. } while (
  5385. !StringRef(parseStringTo(AsmToken::EndOfStatement)).contains(Delimiter));
  5386. return parseEOL();
  5387. }
  5388. /// parseDirectiveInclude
  5389. /// ::= include <filename>
  5390. /// | include filename
  5391. bool MasmParser::parseDirectiveInclude() {
  5392. // Allow the strings to have escaped octal character sequence.
  5393. std::string Filename;
  5394. SMLoc IncludeLoc = getTok().getLoc();
  5395. if (parseAngleBracketString(Filename))
  5396. Filename = parseStringTo(AsmToken::EndOfStatement);
  5397. if (check(Filename.empty(), "missing filename in 'include' directive") ||
  5398. check(getTok().isNot(AsmToken::EndOfStatement),
  5399. "unexpected token in 'include' directive") ||
  5400. // Attempt to switch the lexer to the included file before consuming the
  5401. // end of statement to avoid losing it when we switch.
  5402. check(enterIncludeFile(Filename), IncludeLoc,
  5403. "Could not find include file '" + Filename + "'"))
  5404. return true;
  5405. return false;
  5406. }
  5407. /// parseDirectiveIf
  5408. /// ::= .if{,eq,ge,gt,le,lt,ne} expression
  5409. bool MasmParser::parseDirectiveIf(SMLoc DirectiveLoc, DirectiveKind DirKind) {
  5410. TheCondStack.push_back(TheCondState);
  5411. TheCondState.TheCond = AsmCond::IfCond;
  5412. if (TheCondState.Ignore) {
  5413. eatToEndOfStatement();
  5414. } else {
  5415. int64_t ExprValue;
  5416. if (parseAbsoluteExpression(ExprValue) || parseEOL())
  5417. return true;
  5418. switch (DirKind) {
  5419. default:
  5420. llvm_unreachable("unsupported directive");
  5421. case DK_IF:
  5422. break;
  5423. case DK_IFE:
  5424. ExprValue = ExprValue == 0;
  5425. break;
  5426. }
  5427. TheCondState.CondMet = ExprValue;
  5428. TheCondState.Ignore = !TheCondState.CondMet;
  5429. }
  5430. return false;
  5431. }
  5432. /// parseDirectiveIfb
  5433. /// ::= .ifb textitem
  5434. bool MasmParser::parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
  5435. TheCondStack.push_back(TheCondState);
  5436. TheCondState.TheCond = AsmCond::IfCond;
  5437. if (TheCondState.Ignore) {
  5438. eatToEndOfStatement();
  5439. } else {
  5440. std::string Str;
  5441. if (parseTextItem(Str))
  5442. return TokError("expected text item parameter for 'ifb' directive");
  5443. if (parseEOL())
  5444. return true;
  5445. TheCondState.CondMet = ExpectBlank == Str.empty();
  5446. TheCondState.Ignore = !TheCondState.CondMet;
  5447. }
  5448. return false;
  5449. }
  5450. /// parseDirectiveIfidn
  5451. /// ::= ifidn textitem, textitem
  5452. bool MasmParser::parseDirectiveIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  5453. bool CaseInsensitive) {
  5454. std::string String1, String2;
  5455. if (parseTextItem(String1)) {
  5456. if (ExpectEqual)
  5457. return TokError("expected text item parameter for 'ifidn' directive");
  5458. return TokError("expected text item parameter for 'ifdif' directive");
  5459. }
  5460. if (Lexer.isNot(AsmToken::Comma)) {
  5461. if (ExpectEqual)
  5462. return TokError(
  5463. "expected comma after first string for 'ifidn' directive");
  5464. return TokError("expected comma after first string for 'ifdif' directive");
  5465. }
  5466. Lex();
  5467. if (parseTextItem(String2)) {
  5468. if (ExpectEqual)
  5469. return TokError("expected text item parameter for 'ifidn' directive");
  5470. return TokError("expected text item parameter for 'ifdif' directive");
  5471. }
  5472. TheCondStack.push_back(TheCondState);
  5473. TheCondState.TheCond = AsmCond::IfCond;
  5474. if (CaseInsensitive)
  5475. TheCondState.CondMet =
  5476. ExpectEqual == (StringRef(String1).equals_insensitive(String2));
  5477. else
  5478. TheCondState.CondMet = ExpectEqual == (String1 == String2);
  5479. TheCondState.Ignore = !TheCondState.CondMet;
  5480. return false;
  5481. }
  5482. /// parseDirectiveIfdef
  5483. /// ::= ifdef symbol
  5484. /// | ifdef variable
  5485. bool MasmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
  5486. TheCondStack.push_back(TheCondState);
  5487. TheCondState.TheCond = AsmCond::IfCond;
  5488. if (TheCondState.Ignore) {
  5489. eatToEndOfStatement();
  5490. } else {
  5491. bool is_defined = false;
  5492. MCRegister Reg;
  5493. SMLoc StartLoc, EndLoc;
  5494. is_defined = (getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc) ==
  5495. MatchOperand_Success);
  5496. if (!is_defined) {
  5497. StringRef Name;
  5498. if (check(parseIdentifier(Name), "expected identifier after 'ifdef'") ||
  5499. parseEOL())
  5500. return true;
  5501. if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) {
  5502. is_defined = true;
  5503. } else if (Variables.find(Name.lower()) != Variables.end()) {
  5504. is_defined = true;
  5505. } else {
  5506. MCSymbol *Sym = getContext().lookupSymbol(Name.lower());
  5507. is_defined = (Sym && !Sym->isUndefined(false));
  5508. }
  5509. }
  5510. TheCondState.CondMet = (is_defined == expect_defined);
  5511. TheCondState.Ignore = !TheCondState.CondMet;
  5512. }
  5513. return false;
  5514. }
  5515. /// parseDirectiveElseIf
  5516. /// ::= elseif expression
  5517. bool MasmParser::parseDirectiveElseIf(SMLoc DirectiveLoc,
  5518. DirectiveKind DirKind) {
  5519. if (TheCondState.TheCond != AsmCond::IfCond &&
  5520. TheCondState.TheCond != AsmCond::ElseIfCond)
  5521. return Error(DirectiveLoc, "Encountered a .elseif that doesn't follow an"
  5522. " .if or an .elseif");
  5523. TheCondState.TheCond = AsmCond::ElseIfCond;
  5524. bool LastIgnoreState = false;
  5525. if (!TheCondStack.empty())
  5526. LastIgnoreState = TheCondStack.back().Ignore;
  5527. if (LastIgnoreState || TheCondState.CondMet) {
  5528. TheCondState.Ignore = true;
  5529. eatToEndOfStatement();
  5530. } else {
  5531. int64_t ExprValue;
  5532. if (parseAbsoluteExpression(ExprValue))
  5533. return true;
  5534. if (parseEOL())
  5535. return true;
  5536. switch (DirKind) {
  5537. default:
  5538. llvm_unreachable("unsupported directive");
  5539. case DK_ELSEIF:
  5540. break;
  5541. case DK_ELSEIFE:
  5542. ExprValue = ExprValue == 0;
  5543. break;
  5544. }
  5545. TheCondState.CondMet = ExprValue;
  5546. TheCondState.Ignore = !TheCondState.CondMet;
  5547. }
  5548. return false;
  5549. }
  5550. /// parseDirectiveElseIfb
  5551. /// ::= elseifb textitem
  5552. bool MasmParser::parseDirectiveElseIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
  5553. if (TheCondState.TheCond != AsmCond::IfCond &&
  5554. TheCondState.TheCond != AsmCond::ElseIfCond)
  5555. return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
  5556. " if or an elseif");
  5557. TheCondState.TheCond = AsmCond::ElseIfCond;
  5558. bool LastIgnoreState = false;
  5559. if (!TheCondStack.empty())
  5560. LastIgnoreState = TheCondStack.back().Ignore;
  5561. if (LastIgnoreState || TheCondState.CondMet) {
  5562. TheCondState.Ignore = true;
  5563. eatToEndOfStatement();
  5564. } else {
  5565. std::string Str;
  5566. if (parseTextItem(Str)) {
  5567. if (ExpectBlank)
  5568. return TokError("expected text item parameter for 'elseifb' directive");
  5569. return TokError("expected text item parameter for 'elseifnb' directive");
  5570. }
  5571. if (parseEOL())
  5572. return true;
  5573. TheCondState.CondMet = ExpectBlank == Str.empty();
  5574. TheCondState.Ignore = !TheCondState.CondMet;
  5575. }
  5576. return false;
  5577. }
  5578. /// parseDirectiveElseIfdef
  5579. /// ::= elseifdef symbol
  5580. /// | elseifdef variable
  5581. bool MasmParser::parseDirectiveElseIfdef(SMLoc DirectiveLoc,
  5582. bool expect_defined) {
  5583. if (TheCondState.TheCond != AsmCond::IfCond &&
  5584. TheCondState.TheCond != AsmCond::ElseIfCond)
  5585. return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
  5586. " if or an elseif");
  5587. TheCondState.TheCond = AsmCond::ElseIfCond;
  5588. bool LastIgnoreState = false;
  5589. if (!TheCondStack.empty())
  5590. LastIgnoreState = TheCondStack.back().Ignore;
  5591. if (LastIgnoreState || TheCondState.CondMet) {
  5592. TheCondState.Ignore = true;
  5593. eatToEndOfStatement();
  5594. } else {
  5595. bool is_defined = false;
  5596. MCRegister Reg;
  5597. SMLoc StartLoc, EndLoc;
  5598. is_defined = (getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc) ==
  5599. MatchOperand_Success);
  5600. if (!is_defined) {
  5601. StringRef Name;
  5602. if (check(parseIdentifier(Name),
  5603. "expected identifier after 'elseifdef'") ||
  5604. parseEOL())
  5605. return true;
  5606. if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) {
  5607. is_defined = true;
  5608. } else if (Variables.find(Name.lower()) != Variables.end()) {
  5609. is_defined = true;
  5610. } else {
  5611. MCSymbol *Sym = getContext().lookupSymbol(Name);
  5612. is_defined = (Sym && !Sym->isUndefined(false));
  5613. }
  5614. }
  5615. TheCondState.CondMet = (is_defined == expect_defined);
  5616. TheCondState.Ignore = !TheCondState.CondMet;
  5617. }
  5618. return false;
  5619. }
  5620. /// parseDirectiveElseIfidn
  5621. /// ::= elseifidn textitem, textitem
  5622. bool MasmParser::parseDirectiveElseIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  5623. bool CaseInsensitive) {
  5624. if (TheCondState.TheCond != AsmCond::IfCond &&
  5625. TheCondState.TheCond != AsmCond::ElseIfCond)
  5626. return Error(DirectiveLoc, "Encountered an elseif that doesn't follow an"
  5627. " if or an elseif");
  5628. TheCondState.TheCond = AsmCond::ElseIfCond;
  5629. bool LastIgnoreState = false;
  5630. if (!TheCondStack.empty())
  5631. LastIgnoreState = TheCondStack.back().Ignore;
  5632. if (LastIgnoreState || TheCondState.CondMet) {
  5633. TheCondState.Ignore = true;
  5634. eatToEndOfStatement();
  5635. } else {
  5636. std::string String1, String2;
  5637. if (parseTextItem(String1)) {
  5638. if (ExpectEqual)
  5639. return TokError(
  5640. "expected text item parameter for 'elseifidn' directive");
  5641. return TokError("expected text item parameter for 'elseifdif' directive");
  5642. }
  5643. if (Lexer.isNot(AsmToken::Comma)) {
  5644. if (ExpectEqual)
  5645. return TokError(
  5646. "expected comma after first string for 'elseifidn' directive");
  5647. return TokError(
  5648. "expected comma after first string for 'elseifdif' directive");
  5649. }
  5650. Lex();
  5651. if (parseTextItem(String2)) {
  5652. if (ExpectEqual)
  5653. return TokError(
  5654. "expected text item parameter for 'elseifidn' directive");
  5655. return TokError("expected text item parameter for 'elseifdif' directive");
  5656. }
  5657. if (CaseInsensitive)
  5658. TheCondState.CondMet =
  5659. ExpectEqual == (StringRef(String1).equals_insensitive(String2));
  5660. else
  5661. TheCondState.CondMet = ExpectEqual == (String1 == String2);
  5662. TheCondState.Ignore = !TheCondState.CondMet;
  5663. }
  5664. return false;
  5665. }
  5666. /// parseDirectiveElse
  5667. /// ::= else
  5668. bool MasmParser::parseDirectiveElse(SMLoc DirectiveLoc) {
  5669. if (parseEOL())
  5670. return true;
  5671. if (TheCondState.TheCond != AsmCond::IfCond &&
  5672. TheCondState.TheCond != AsmCond::ElseIfCond)
  5673. return Error(DirectiveLoc, "Encountered an else that doesn't follow an if"
  5674. " or an elseif");
  5675. TheCondState.TheCond = AsmCond::ElseCond;
  5676. bool LastIgnoreState = false;
  5677. if (!TheCondStack.empty())
  5678. LastIgnoreState = TheCondStack.back().Ignore;
  5679. if (LastIgnoreState || TheCondState.CondMet)
  5680. TheCondState.Ignore = true;
  5681. else
  5682. TheCondState.Ignore = false;
  5683. return false;
  5684. }
  5685. /// parseDirectiveEnd
  5686. /// ::= end
  5687. bool MasmParser::parseDirectiveEnd(SMLoc DirectiveLoc) {
  5688. if (parseEOL())
  5689. return true;
  5690. while (Lexer.isNot(AsmToken::Eof))
  5691. Lexer.Lex();
  5692. return false;
  5693. }
  5694. /// parseDirectiveError
  5695. /// ::= .err [message]
  5696. bool MasmParser::parseDirectiveError(SMLoc DirectiveLoc) {
  5697. if (!TheCondStack.empty()) {
  5698. if (TheCondStack.back().Ignore) {
  5699. eatToEndOfStatement();
  5700. return false;
  5701. }
  5702. }
  5703. std::string Message = ".err directive invoked in source file";
  5704. if (Lexer.isNot(AsmToken::EndOfStatement))
  5705. Message = parseStringTo(AsmToken::EndOfStatement);
  5706. Lex();
  5707. return Error(DirectiveLoc, Message);
  5708. }
  5709. /// parseDirectiveErrorIfb
  5710. /// ::= .errb textitem[, message]
  5711. bool MasmParser::parseDirectiveErrorIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
  5712. if (!TheCondStack.empty()) {
  5713. if (TheCondStack.back().Ignore) {
  5714. eatToEndOfStatement();
  5715. return false;
  5716. }
  5717. }
  5718. std::string Text;
  5719. if (parseTextItem(Text))
  5720. return Error(getTok().getLoc(), "missing text item in '.errb' directive");
  5721. std::string Message = ".errb directive invoked in source file";
  5722. if (Lexer.isNot(AsmToken::EndOfStatement)) {
  5723. if (parseToken(AsmToken::Comma))
  5724. return addErrorSuffix(" in '.errb' directive");
  5725. Message = parseStringTo(AsmToken::EndOfStatement);
  5726. }
  5727. Lex();
  5728. if (Text.empty() == ExpectBlank)
  5729. return Error(DirectiveLoc, Message);
  5730. return false;
  5731. }
  5732. /// parseDirectiveErrorIfdef
  5733. /// ::= .errdef name[, message]
  5734. bool MasmParser::parseDirectiveErrorIfdef(SMLoc DirectiveLoc,
  5735. bool ExpectDefined) {
  5736. if (!TheCondStack.empty()) {
  5737. if (TheCondStack.back().Ignore) {
  5738. eatToEndOfStatement();
  5739. return false;
  5740. }
  5741. }
  5742. bool IsDefined = false;
  5743. MCRegister Reg;
  5744. SMLoc StartLoc, EndLoc;
  5745. IsDefined = (getTargetParser().tryParseRegister(Reg, StartLoc, EndLoc) ==
  5746. MatchOperand_Success);
  5747. if (!IsDefined) {
  5748. StringRef Name;
  5749. if (check(parseIdentifier(Name), "expected identifier after '.errdef'"))
  5750. return true;
  5751. if (BuiltinSymbolMap.find(Name.lower()) != BuiltinSymbolMap.end()) {
  5752. IsDefined = true;
  5753. } else if (Variables.find(Name.lower()) != Variables.end()) {
  5754. IsDefined = true;
  5755. } else {
  5756. MCSymbol *Sym = getContext().lookupSymbol(Name);
  5757. IsDefined = (Sym && !Sym->isUndefined(false));
  5758. }
  5759. }
  5760. std::string Message = ".errdef directive invoked in source file";
  5761. if (Lexer.isNot(AsmToken::EndOfStatement)) {
  5762. if (parseToken(AsmToken::Comma))
  5763. return addErrorSuffix(" in '.errdef' directive");
  5764. Message = parseStringTo(AsmToken::EndOfStatement);
  5765. }
  5766. Lex();
  5767. if (IsDefined == ExpectDefined)
  5768. return Error(DirectiveLoc, Message);
  5769. return false;
  5770. }
  5771. /// parseDirectiveErrorIfidn
  5772. /// ::= .erridn textitem, textitem[, message]
  5773. bool MasmParser::parseDirectiveErrorIfidn(SMLoc DirectiveLoc, bool ExpectEqual,
  5774. bool CaseInsensitive) {
  5775. if (!TheCondStack.empty()) {
  5776. if (TheCondStack.back().Ignore) {
  5777. eatToEndOfStatement();
  5778. return false;
  5779. }
  5780. }
  5781. std::string String1, String2;
  5782. if (parseTextItem(String1)) {
  5783. if (ExpectEqual)
  5784. return TokError("expected string parameter for '.erridn' directive");
  5785. return TokError("expected string parameter for '.errdif' directive");
  5786. }
  5787. if (Lexer.isNot(AsmToken::Comma)) {
  5788. if (ExpectEqual)
  5789. return TokError(
  5790. "expected comma after first string for '.erridn' directive");
  5791. return TokError(
  5792. "expected comma after first string for '.errdif' directive");
  5793. }
  5794. Lex();
  5795. if (parseTextItem(String2)) {
  5796. if (ExpectEqual)
  5797. return TokError("expected string parameter for '.erridn' directive");
  5798. return TokError("expected string parameter for '.errdif' directive");
  5799. }
  5800. std::string Message;
  5801. if (ExpectEqual)
  5802. Message = ".erridn directive invoked in source file";
  5803. else
  5804. Message = ".errdif directive invoked in source file";
  5805. if (Lexer.isNot(AsmToken::EndOfStatement)) {
  5806. if (parseToken(AsmToken::Comma))
  5807. return addErrorSuffix(" in '.erridn' directive");
  5808. Message = parseStringTo(AsmToken::EndOfStatement);
  5809. }
  5810. Lex();
  5811. if (CaseInsensitive)
  5812. TheCondState.CondMet =
  5813. ExpectEqual == (StringRef(String1).equals_insensitive(String2));
  5814. else
  5815. TheCondState.CondMet = ExpectEqual == (String1 == String2);
  5816. TheCondState.Ignore = !TheCondState.CondMet;
  5817. if ((CaseInsensitive &&
  5818. ExpectEqual == StringRef(String1).equals_insensitive(String2)) ||
  5819. (ExpectEqual == (String1 == String2)))
  5820. return Error(DirectiveLoc, Message);
  5821. return false;
  5822. }
  5823. /// parseDirectiveErrorIfe
  5824. /// ::= .erre expression[, message]
  5825. bool MasmParser::parseDirectiveErrorIfe(SMLoc DirectiveLoc, bool ExpectZero) {
  5826. if (!TheCondStack.empty()) {
  5827. if (TheCondStack.back().Ignore) {
  5828. eatToEndOfStatement();
  5829. return false;
  5830. }
  5831. }
  5832. int64_t ExprValue;
  5833. if (parseAbsoluteExpression(ExprValue))
  5834. return addErrorSuffix(" in '.erre' directive");
  5835. std::string Message = ".erre directive invoked in source file";
  5836. if (Lexer.isNot(AsmToken::EndOfStatement)) {
  5837. if (parseToken(AsmToken::Comma))
  5838. return addErrorSuffix(" in '.erre' directive");
  5839. Message = parseStringTo(AsmToken::EndOfStatement);
  5840. }
  5841. Lex();
  5842. if ((ExprValue == 0) == ExpectZero)
  5843. return Error(DirectiveLoc, Message);
  5844. return false;
  5845. }
  5846. /// parseDirectiveEndIf
  5847. /// ::= .endif
  5848. bool MasmParser::parseDirectiveEndIf(SMLoc DirectiveLoc) {
  5849. if (parseEOL())
  5850. return true;
  5851. if ((TheCondState.TheCond == AsmCond::NoCond) || TheCondStack.empty())
  5852. return Error(DirectiveLoc, "Encountered a .endif that doesn't follow "
  5853. "an .if or .else");
  5854. if (!TheCondStack.empty()) {
  5855. TheCondState = TheCondStack.back();
  5856. TheCondStack.pop_back();
  5857. }
  5858. return false;
  5859. }
  5860. void MasmParser::initializeDirectiveKindMap() {
  5861. DirectiveKindMap["="] = DK_ASSIGN;
  5862. DirectiveKindMap["equ"] = DK_EQU;
  5863. DirectiveKindMap["textequ"] = DK_TEXTEQU;
  5864. // DirectiveKindMap[".ascii"] = DK_ASCII;
  5865. // DirectiveKindMap[".asciz"] = DK_ASCIZ;
  5866. // DirectiveKindMap[".string"] = DK_STRING;
  5867. DirectiveKindMap["byte"] = DK_BYTE;
  5868. DirectiveKindMap["sbyte"] = DK_SBYTE;
  5869. DirectiveKindMap["word"] = DK_WORD;
  5870. DirectiveKindMap["sword"] = DK_SWORD;
  5871. DirectiveKindMap["dword"] = DK_DWORD;
  5872. DirectiveKindMap["sdword"] = DK_SDWORD;
  5873. DirectiveKindMap["fword"] = DK_FWORD;
  5874. DirectiveKindMap["qword"] = DK_QWORD;
  5875. DirectiveKindMap["sqword"] = DK_SQWORD;
  5876. DirectiveKindMap["real4"] = DK_REAL4;
  5877. DirectiveKindMap["real8"] = DK_REAL8;
  5878. DirectiveKindMap["real10"] = DK_REAL10;
  5879. DirectiveKindMap["align"] = DK_ALIGN;
  5880. DirectiveKindMap["even"] = DK_EVEN;
  5881. DirectiveKindMap["org"] = DK_ORG;
  5882. DirectiveKindMap["extern"] = DK_EXTERN;
  5883. DirectiveKindMap["extrn"] = DK_EXTERN;
  5884. DirectiveKindMap["public"] = DK_PUBLIC;
  5885. // DirectiveKindMap[".comm"] = DK_COMM;
  5886. DirectiveKindMap["comment"] = DK_COMMENT;
  5887. DirectiveKindMap["include"] = DK_INCLUDE;
  5888. DirectiveKindMap["repeat"] = DK_REPEAT;
  5889. DirectiveKindMap["rept"] = DK_REPEAT;
  5890. DirectiveKindMap["while"] = DK_WHILE;
  5891. DirectiveKindMap["for"] = DK_FOR;
  5892. DirectiveKindMap["irp"] = DK_FOR;
  5893. DirectiveKindMap["forc"] = DK_FORC;
  5894. DirectiveKindMap["irpc"] = DK_FORC;
  5895. DirectiveKindMap["if"] = DK_IF;
  5896. DirectiveKindMap["ife"] = DK_IFE;
  5897. DirectiveKindMap["ifb"] = DK_IFB;
  5898. DirectiveKindMap["ifnb"] = DK_IFNB;
  5899. DirectiveKindMap["ifdef"] = DK_IFDEF;
  5900. DirectiveKindMap["ifndef"] = DK_IFNDEF;
  5901. DirectiveKindMap["ifdif"] = DK_IFDIF;
  5902. DirectiveKindMap["ifdifi"] = DK_IFDIFI;
  5903. DirectiveKindMap["ifidn"] = DK_IFIDN;
  5904. DirectiveKindMap["ifidni"] = DK_IFIDNI;
  5905. DirectiveKindMap["elseif"] = DK_ELSEIF;
  5906. DirectiveKindMap["elseifdef"] = DK_ELSEIFDEF;
  5907. DirectiveKindMap["elseifndef"] = DK_ELSEIFNDEF;
  5908. DirectiveKindMap["elseifdif"] = DK_ELSEIFDIF;
  5909. DirectiveKindMap["elseifidn"] = DK_ELSEIFIDN;
  5910. DirectiveKindMap["else"] = DK_ELSE;
  5911. DirectiveKindMap["end"] = DK_END;
  5912. DirectiveKindMap["endif"] = DK_ENDIF;
  5913. // DirectiveKindMap[".file"] = DK_FILE;
  5914. // DirectiveKindMap[".line"] = DK_LINE;
  5915. // DirectiveKindMap[".loc"] = DK_LOC;
  5916. // DirectiveKindMap[".stabs"] = DK_STABS;
  5917. // DirectiveKindMap[".cv_file"] = DK_CV_FILE;
  5918. // DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
  5919. // DirectiveKindMap[".cv_loc"] = DK_CV_LOC;
  5920. // DirectiveKindMap[".cv_linetable"] = DK_CV_LINETABLE;
  5921. // DirectiveKindMap[".cv_inline_linetable"] = DK_CV_INLINE_LINETABLE;
  5922. // DirectiveKindMap[".cv_inline_site_id"] = DK_CV_INLINE_SITE_ID;
  5923. // DirectiveKindMap[".cv_def_range"] = DK_CV_DEF_RANGE;
  5924. // DirectiveKindMap[".cv_string"] = DK_CV_STRING;
  5925. // DirectiveKindMap[".cv_stringtable"] = DK_CV_STRINGTABLE;
  5926. // DirectiveKindMap[".cv_filechecksums"] = DK_CV_FILECHECKSUMS;
  5927. // DirectiveKindMap[".cv_filechecksumoffset"] = DK_CV_FILECHECKSUM_OFFSET;
  5928. // DirectiveKindMap[".cv_fpo_data"] = DK_CV_FPO_DATA;
  5929. // DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
  5930. // DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
  5931. // DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
  5932. // DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
  5933. // DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
  5934. // DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
  5935. // DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
  5936. // DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
  5937. // DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
  5938. // DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
  5939. // DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
  5940. // DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
  5941. // DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
  5942. // DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
  5943. // DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
  5944. // DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
  5945. // DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
  5946. // DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
  5947. // DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
  5948. // DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
  5949. // DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
  5950. // DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
  5951. DirectiveKindMap["macro"] = DK_MACRO;
  5952. DirectiveKindMap["exitm"] = DK_EXITM;
  5953. DirectiveKindMap["endm"] = DK_ENDM;
  5954. DirectiveKindMap["purge"] = DK_PURGE;
  5955. DirectiveKindMap[".err"] = DK_ERR;
  5956. DirectiveKindMap[".errb"] = DK_ERRB;
  5957. DirectiveKindMap[".errnb"] = DK_ERRNB;
  5958. DirectiveKindMap[".errdef"] = DK_ERRDEF;
  5959. DirectiveKindMap[".errndef"] = DK_ERRNDEF;
  5960. DirectiveKindMap[".errdif"] = DK_ERRDIF;
  5961. DirectiveKindMap[".errdifi"] = DK_ERRDIFI;
  5962. DirectiveKindMap[".erridn"] = DK_ERRIDN;
  5963. DirectiveKindMap[".erridni"] = DK_ERRIDNI;
  5964. DirectiveKindMap[".erre"] = DK_ERRE;
  5965. DirectiveKindMap[".errnz"] = DK_ERRNZ;
  5966. DirectiveKindMap[".pushframe"] = DK_PUSHFRAME;
  5967. DirectiveKindMap[".pushreg"] = DK_PUSHREG;
  5968. DirectiveKindMap[".savereg"] = DK_SAVEREG;
  5969. DirectiveKindMap[".savexmm128"] = DK_SAVEXMM128;
  5970. DirectiveKindMap[".setframe"] = DK_SETFRAME;
  5971. DirectiveKindMap[".radix"] = DK_RADIX;
  5972. DirectiveKindMap["db"] = DK_DB;
  5973. DirectiveKindMap["dd"] = DK_DD;
  5974. DirectiveKindMap["df"] = DK_DF;
  5975. DirectiveKindMap["dq"] = DK_DQ;
  5976. DirectiveKindMap["dw"] = DK_DW;
  5977. DirectiveKindMap["echo"] = DK_ECHO;
  5978. DirectiveKindMap["struc"] = DK_STRUCT;
  5979. DirectiveKindMap["struct"] = DK_STRUCT;
  5980. DirectiveKindMap["union"] = DK_UNION;
  5981. DirectiveKindMap["ends"] = DK_ENDS;
  5982. }
  5983. bool MasmParser::isMacroLikeDirective() {
  5984. if (getLexer().is(AsmToken::Identifier)) {
  5985. bool IsMacroLike = StringSwitch<bool>(getTok().getIdentifier())
  5986. .CasesLower("repeat", "rept", true)
  5987. .CaseLower("while", true)
  5988. .CasesLower("for", "irp", true)
  5989. .CasesLower("forc", "irpc", true)
  5990. .Default(false);
  5991. if (IsMacroLike)
  5992. return true;
  5993. }
  5994. if (peekTok().is(AsmToken::Identifier) &&
  5995. peekTok().getIdentifier().equals_insensitive("macro"))
  5996. return true;
  5997. return false;
  5998. }
  5999. MCAsmMacro *MasmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {
  6000. AsmToken EndToken, StartToken = getTok();
  6001. unsigned NestLevel = 0;
  6002. while (true) {
  6003. // Check whether we have reached the end of the file.
  6004. if (getLexer().is(AsmToken::Eof)) {
  6005. printError(DirectiveLoc, "no matching 'endm' in definition");
  6006. return nullptr;
  6007. }
  6008. if (isMacroLikeDirective())
  6009. ++NestLevel;
  6010. // Otherwise, check whether we have reached the endm.
  6011. if (Lexer.is(AsmToken::Identifier) &&
  6012. getTok().getIdentifier().equals_insensitive("endm")) {
  6013. if (NestLevel == 0) {
  6014. EndToken = getTok();
  6015. Lex();
  6016. if (Lexer.isNot(AsmToken::EndOfStatement)) {
  6017. printError(getTok().getLoc(), "unexpected token in 'endm' directive");
  6018. return nullptr;
  6019. }
  6020. break;
  6021. }
  6022. --NestLevel;
  6023. }
  6024. // Otherwise, scan till the end of the statement.
  6025. eatToEndOfStatement();
  6026. }
  6027. const char *BodyStart = StartToken.getLoc().getPointer();
  6028. const char *BodyEnd = EndToken.getLoc().getPointer();
  6029. StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
  6030. // We Are Anonymous.
  6031. MacroLikeBodies.emplace_back(StringRef(), Body, MCAsmMacroParameters());
  6032. return &MacroLikeBodies.back();
  6033. }
  6034. bool MasmParser::expandStatement(SMLoc Loc) {
  6035. std::string Body = parseStringTo(AsmToken::EndOfStatement);
  6036. SMLoc EndLoc = getTok().getLoc();
  6037. MCAsmMacroParameters Parameters;
  6038. MCAsmMacroArguments Arguments;
  6039. StringMap<std::string> BuiltinValues;
  6040. for (const auto &S : BuiltinSymbolMap) {
  6041. const BuiltinSymbol &Sym = S.getValue();
  6042. if (std::optional<std::string> Text = evaluateBuiltinTextMacro(Sym, Loc)) {
  6043. BuiltinValues[S.getKey().lower()] = std::move(*Text);
  6044. }
  6045. }
  6046. for (const auto &B : BuiltinValues) {
  6047. MCAsmMacroParameter P;
  6048. MCAsmMacroArgument A;
  6049. P.Name = B.getKey();
  6050. P.Required = true;
  6051. A.push_back(AsmToken(AsmToken::String, B.getValue()));
  6052. Parameters.push_back(std::move(P));
  6053. Arguments.push_back(std::move(A));
  6054. }
  6055. for (const auto &V : Variables) {
  6056. const Variable &Var = V.getValue();
  6057. if (Var.IsText) {
  6058. MCAsmMacroParameter P;
  6059. MCAsmMacroArgument A;
  6060. P.Name = Var.Name;
  6061. P.Required = true;
  6062. A.push_back(AsmToken(AsmToken::String, Var.TextValue));
  6063. Parameters.push_back(std::move(P));
  6064. Arguments.push_back(std::move(A));
  6065. }
  6066. }
  6067. MacroLikeBodies.emplace_back(StringRef(), Body, Parameters);
  6068. MCAsmMacro M = MacroLikeBodies.back();
  6069. // Expand the statement in a new buffer.
  6070. SmallString<80> Buf;
  6071. raw_svector_ostream OS(Buf);
  6072. if (expandMacro(OS, M.Body, M.Parameters, Arguments, M.Locals, EndLoc))
  6073. return true;
  6074. std::unique_ptr<MemoryBuffer> Expansion =
  6075. MemoryBuffer::getMemBufferCopy(OS.str(), "<expansion>");
  6076. // Jump to the expanded statement and prime the lexer.
  6077. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Expansion), EndLoc);
  6078. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
  6079. EndStatementAtEOFStack.push_back(false);
  6080. Lex();
  6081. return false;
  6082. }
  6083. void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
  6084. raw_svector_ostream &OS) {
  6085. instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/getTok().getLoc(), OS);
  6086. }
  6087. void MasmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
  6088. SMLoc ExitLoc,
  6089. raw_svector_ostream &OS) {
  6090. OS << "endm\n";
  6091. std::unique_ptr<MemoryBuffer> Instantiation =
  6092. MemoryBuffer::getMemBufferCopy(OS.str(), "<instantiation>");
  6093. // Create the macro instantiation object and add to the current macro
  6094. // instantiation stack.
  6095. MacroInstantiation *MI = new MacroInstantiation{DirectiveLoc, CurBuffer,
  6096. ExitLoc, TheCondStack.size()};
  6097. ActiveMacros.push_back(MI);
  6098. // Jump to the macro instantiation and prime the lexer.
  6099. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
  6100. Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
  6101. EndStatementAtEOFStack.push_back(true);
  6102. Lex();
  6103. }
  6104. /// parseDirectiveRepeat
  6105. /// ::= ("repeat" | "rept") count
  6106. /// body
  6107. /// endm
  6108. bool MasmParser::parseDirectiveRepeat(SMLoc DirectiveLoc, StringRef Dir) {
  6109. const MCExpr *CountExpr;
  6110. SMLoc CountLoc = getTok().getLoc();
  6111. if (parseExpression(CountExpr))
  6112. return true;
  6113. int64_t Count;
  6114. if (!CountExpr->evaluateAsAbsolute(Count, getStreamer().getAssemblerPtr())) {
  6115. return Error(CountLoc, "unexpected token in '" + Dir + "' directive");
  6116. }
  6117. if (check(Count < 0, CountLoc, "Count is negative") || parseEOL())
  6118. return true;
  6119. // Lex the repeat definition.
  6120. MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
  6121. if (!M)
  6122. return true;
  6123. // Macro instantiation is lexical, unfortunately. We construct a new buffer
  6124. // to hold the macro body with substitutions.
  6125. SmallString<256> Buf;
  6126. raw_svector_ostream OS(Buf);
  6127. while (Count--) {
  6128. if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
  6129. getTok().getLoc()))
  6130. return true;
  6131. }
  6132. instantiateMacroLikeBody(M, DirectiveLoc, OS);
  6133. return false;
  6134. }
  6135. /// parseDirectiveWhile
  6136. /// ::= "while" expression
  6137. /// body
  6138. /// endm
  6139. bool MasmParser::parseDirectiveWhile(SMLoc DirectiveLoc) {
  6140. const MCExpr *CondExpr;
  6141. SMLoc CondLoc = getTok().getLoc();
  6142. if (parseExpression(CondExpr))
  6143. return true;
  6144. // Lex the repeat definition.
  6145. MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
  6146. if (!M)
  6147. return true;
  6148. // Macro instantiation is lexical, unfortunately. We construct a new buffer
  6149. // to hold the macro body with substitutions.
  6150. SmallString<256> Buf;
  6151. raw_svector_ostream OS(Buf);
  6152. int64_t Condition;
  6153. if (!CondExpr->evaluateAsAbsolute(Condition, getStreamer().getAssemblerPtr()))
  6154. return Error(CondLoc, "expected absolute expression in 'while' directive");
  6155. if (Condition) {
  6156. // Instantiate the macro, then resume at this directive to recheck the
  6157. // condition.
  6158. if (expandMacro(OS, M->Body, std::nullopt, std::nullopt, M->Locals,
  6159. getTok().getLoc()))
  6160. return true;
  6161. instantiateMacroLikeBody(M, DirectiveLoc, /*ExitLoc=*/DirectiveLoc, OS);
  6162. }
  6163. return false;
  6164. }
  6165. /// parseDirectiveFor
  6166. /// ::= ("for" | "irp") symbol [":" qualifier], <values>
  6167. /// body
  6168. /// endm
  6169. bool MasmParser::parseDirectiveFor(SMLoc DirectiveLoc, StringRef Dir) {
  6170. MCAsmMacroParameter Parameter;
  6171. MCAsmMacroArguments A;
  6172. if (check(parseIdentifier(Parameter.Name),
  6173. "expected identifier in '" + Dir + "' directive"))
  6174. return true;
  6175. // Parse optional qualifier (default value, or "req")
  6176. if (parseOptionalToken(AsmToken::Colon)) {
  6177. if (parseOptionalToken(AsmToken::Equal)) {
  6178. // Default value
  6179. SMLoc ParamLoc;
  6180. ParamLoc = Lexer.getLoc();
  6181. if (parseMacroArgument(nullptr, Parameter.Value))
  6182. return true;
  6183. } else {
  6184. SMLoc QualLoc;
  6185. StringRef Qualifier;
  6186. QualLoc = Lexer.getLoc();
  6187. if (parseIdentifier(Qualifier))
  6188. return Error(QualLoc, "missing parameter qualifier for "
  6189. "'" +
  6190. Parameter.Name + "' in '" + Dir +
  6191. "' directive");
  6192. if (Qualifier.equals_insensitive("req"))
  6193. Parameter.Required = true;
  6194. else
  6195. return Error(QualLoc,
  6196. Qualifier + " is not a valid parameter qualifier for '" +
  6197. Parameter.Name + "' in '" + Dir + "' directive");
  6198. }
  6199. }
  6200. if (parseToken(AsmToken::Comma,
  6201. "expected comma in '" + Dir + "' directive") ||
  6202. parseToken(AsmToken::Less,
  6203. "values in '" + Dir +
  6204. "' directive must be enclosed in angle brackets"))
  6205. return true;
  6206. while (true) {
  6207. A.emplace_back();
  6208. if (parseMacroArgument(&Parameter, A.back(), /*EndTok=*/AsmToken::Greater))
  6209. return addErrorSuffix(" in arguments for '" + Dir + "' directive");
  6210. // If we see a comma, continue, and allow line continuation.
  6211. if (!parseOptionalToken(AsmToken::Comma))
  6212. break;
  6213. parseOptionalToken(AsmToken::EndOfStatement);
  6214. }
  6215. if (parseToken(AsmToken::Greater,
  6216. "values in '" + Dir +
  6217. "' directive must be enclosed in angle brackets") ||
  6218. parseEOL())
  6219. return true;
  6220. // Lex the for definition.
  6221. MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
  6222. if (!M)
  6223. return true;
  6224. // Macro instantiation is lexical, unfortunately. We construct a new buffer
  6225. // to hold the macro body with substitutions.
  6226. SmallString<256> Buf;
  6227. raw_svector_ostream OS(Buf);
  6228. for (const MCAsmMacroArgument &Arg : A) {
  6229. if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
  6230. return true;
  6231. }
  6232. instantiateMacroLikeBody(M, DirectiveLoc, OS);
  6233. return false;
  6234. }
  6235. /// parseDirectiveForc
  6236. /// ::= ("forc" | "irpc") symbol, <string>
  6237. /// body
  6238. /// endm
  6239. bool MasmParser::parseDirectiveForc(SMLoc DirectiveLoc, StringRef Directive) {
  6240. MCAsmMacroParameter Parameter;
  6241. std::string Argument;
  6242. if (check(parseIdentifier(Parameter.Name),
  6243. "expected identifier in '" + Directive + "' directive") ||
  6244. parseToken(AsmToken::Comma,
  6245. "expected comma in '" + Directive + "' directive"))
  6246. return true;
  6247. if (parseAngleBracketString(Argument)) {
  6248. // Match ml64.exe; treat all characters to end of statement as a string,
  6249. // ignoring comment markers, then discard anything following a space (using
  6250. // the C locale).
  6251. Argument = parseStringTo(AsmToken::EndOfStatement);
  6252. if (getTok().is(AsmToken::EndOfStatement))
  6253. Argument += getTok().getString();
  6254. size_t End = 0;
  6255. for (; End < Argument.size(); ++End) {
  6256. if (isSpace(Argument[End]))
  6257. break;
  6258. }
  6259. Argument.resize(End);
  6260. }
  6261. if (parseEOL())
  6262. return true;
  6263. // Lex the irpc definition.
  6264. MCAsmMacro *M = parseMacroLikeBody(DirectiveLoc);
  6265. if (!M)
  6266. return true;
  6267. // Macro instantiation is lexical, unfortunately. We construct a new buffer
  6268. // to hold the macro body with substitutions.
  6269. SmallString<256> Buf;
  6270. raw_svector_ostream OS(Buf);
  6271. StringRef Values(Argument);
  6272. for (std::size_t I = 0, End = Values.size(); I != End; ++I) {
  6273. MCAsmMacroArgument Arg;
  6274. Arg.emplace_back(AsmToken::Identifier, Values.slice(I, I + 1));
  6275. if (expandMacro(OS, M->Body, Parameter, Arg, M->Locals, getTok().getLoc()))
  6276. return true;
  6277. }
  6278. instantiateMacroLikeBody(M, DirectiveLoc, OS);
  6279. return false;
  6280. }
  6281. bool MasmParser::parseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
  6282. size_t Len) {
  6283. const MCExpr *Value;
  6284. SMLoc ExprLoc = getLexer().getLoc();
  6285. if (parseExpression(Value))
  6286. return true;
  6287. const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
  6288. if (!MCE)
  6289. return Error(ExprLoc, "unexpected expression in _emit");
  6290. uint64_t IntValue = MCE->getValue();
  6291. if (!isUInt<8>(IntValue) && !isInt<8>(IntValue))
  6292. return Error(ExprLoc, "literal value out of range for directive");
  6293. Info.AsmRewrites->emplace_back(AOK_Emit, IDLoc, Len);
  6294. return false;
  6295. }
  6296. bool MasmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
  6297. const MCExpr *Value;
  6298. SMLoc ExprLoc = getLexer().getLoc();
  6299. if (parseExpression(Value))
  6300. return true;
  6301. const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
  6302. if (!MCE)
  6303. return Error(ExprLoc, "unexpected expression in align");
  6304. uint64_t IntValue = MCE->getValue();
  6305. if (!isPowerOf2_64(IntValue))
  6306. return Error(ExprLoc, "literal value not a power of two greater then zero");
  6307. Info.AsmRewrites->emplace_back(AOK_Align, IDLoc, 5, Log2_64(IntValue));
  6308. return false;
  6309. }
  6310. bool MasmParser::parseDirectiveRadix(SMLoc DirectiveLoc) {
  6311. const SMLoc Loc = getLexer().getLoc();
  6312. std::string RadixStringRaw = parseStringTo(AsmToken::EndOfStatement);
  6313. StringRef RadixString = StringRef(RadixStringRaw).trim();
  6314. unsigned Radix;
  6315. if (RadixString.getAsInteger(10, Radix)) {
  6316. return Error(Loc,
  6317. "radix must be a decimal number in the range 2 to 16; was " +
  6318. RadixString);
  6319. }
  6320. if (Radix < 2 || Radix > 16)
  6321. return Error(Loc, "radix must be in the range 2 to 16; was " +
  6322. std::to_string(Radix));
  6323. getLexer().setMasmDefaultRadix(Radix);
  6324. return false;
  6325. }
  6326. /// parseDirectiveEcho
  6327. /// ::= "echo" message
  6328. bool MasmParser::parseDirectiveEcho(SMLoc DirectiveLoc) {
  6329. std::string Message = parseStringTo(AsmToken::EndOfStatement);
  6330. llvm::outs() << Message;
  6331. if (!StringRef(Message).endswith("\n"))
  6332. llvm::outs() << '\n';
  6333. return false;
  6334. }
  6335. // We are comparing pointers, but the pointers are relative to a single string.
  6336. // Thus, this should always be deterministic.
  6337. static int rewritesSort(const AsmRewrite *AsmRewriteA,
  6338. const AsmRewrite *AsmRewriteB) {
  6339. if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
  6340. return -1;
  6341. if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
  6342. return 1;
  6343. // It's possible to have a SizeDirective, Imm/ImmPrefix and an Input/Output
  6344. // rewrite to the same location. Make sure the SizeDirective rewrite is
  6345. // performed first, then the Imm/ImmPrefix and finally the Input/Output. This
  6346. // ensures the sort algorithm is stable.
  6347. if (AsmRewritePrecedence[AsmRewriteA->Kind] >
  6348. AsmRewritePrecedence[AsmRewriteB->Kind])
  6349. return -1;
  6350. if (AsmRewritePrecedence[AsmRewriteA->Kind] <
  6351. AsmRewritePrecedence[AsmRewriteB->Kind])
  6352. return 1;
  6353. llvm_unreachable("Unstable rewrite sort.");
  6354. }
  6355. bool MasmParser::defineMacro(StringRef Name, StringRef Value) {
  6356. Variable &Var = Variables[Name.lower()];
  6357. if (Var.Name.empty()) {
  6358. Var.Name = Name;
  6359. } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) {
  6360. return Error(SMLoc(), "invalid variable redefinition");
  6361. } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION &&
  6362. Warning(SMLoc(), "redefining '" + Name +
  6363. "', already defined on the command line")) {
  6364. return true;
  6365. }
  6366. Var.Redefinable = Variable::WARN_ON_REDEFINITION;
  6367. Var.IsText = true;
  6368. Var.TextValue = Value.str();
  6369. return false;
  6370. }
  6371. bool MasmParser::lookUpField(StringRef Name, AsmFieldInfo &Info) const {
  6372. const std::pair<StringRef, StringRef> BaseMember = Name.split('.');
  6373. const StringRef Base = BaseMember.first, Member = BaseMember.second;
  6374. return lookUpField(Base, Member, Info);
  6375. }
  6376. bool MasmParser::lookUpField(StringRef Base, StringRef Member,
  6377. AsmFieldInfo &Info) const {
  6378. if (Base.empty())
  6379. return true;
  6380. AsmFieldInfo BaseInfo;
  6381. if (Base.contains('.') && !lookUpField(Base, BaseInfo))
  6382. Base = BaseInfo.Type.Name;
  6383. auto StructIt = Structs.find(Base.lower());
  6384. auto TypeIt = KnownType.find(Base.lower());
  6385. if (TypeIt != KnownType.end()) {
  6386. StructIt = Structs.find(TypeIt->second.Name.lower());
  6387. }
  6388. if (StructIt != Structs.end())
  6389. return lookUpField(StructIt->second, Member, Info);
  6390. return true;
  6391. }
  6392. bool MasmParser::lookUpField(const StructInfo &Structure, StringRef Member,
  6393. AsmFieldInfo &Info) const {
  6394. if (Member.empty()) {
  6395. Info.Type.Name = Structure.Name;
  6396. Info.Type.Size = Structure.Size;
  6397. Info.Type.ElementSize = Structure.Size;
  6398. Info.Type.Length = 1;
  6399. return false;
  6400. }
  6401. std::pair<StringRef, StringRef> Split = Member.split('.');
  6402. const StringRef FieldName = Split.first, FieldMember = Split.second;
  6403. auto StructIt = Structs.find(FieldName.lower());
  6404. if (StructIt != Structs.end())
  6405. return lookUpField(StructIt->second, FieldMember, Info);
  6406. auto FieldIt = Structure.FieldsByName.find(FieldName.lower());
  6407. if (FieldIt == Structure.FieldsByName.end())
  6408. return true;
  6409. const FieldInfo &Field = Structure.Fields[FieldIt->second];
  6410. if (FieldMember.empty()) {
  6411. Info.Offset += Field.Offset;
  6412. Info.Type.Size = Field.SizeOf;
  6413. Info.Type.ElementSize = Field.Type;
  6414. Info.Type.Length = Field.LengthOf;
  6415. if (Field.Contents.FT == FT_STRUCT)
  6416. Info.Type.Name = Field.Contents.StructInfo.Structure.Name;
  6417. else
  6418. Info.Type.Name = "";
  6419. return false;
  6420. }
  6421. if (Field.Contents.FT != FT_STRUCT)
  6422. return true;
  6423. const StructFieldInfo &StructInfo = Field.Contents.StructInfo;
  6424. if (lookUpField(StructInfo.Structure, FieldMember, Info))
  6425. return true;
  6426. Info.Offset += Field.Offset;
  6427. return false;
  6428. }
  6429. bool MasmParser::lookUpType(StringRef Name, AsmTypeInfo &Info) const {
  6430. unsigned Size = StringSwitch<unsigned>(Name)
  6431. .CasesLower("byte", "db", "sbyte", 1)
  6432. .CasesLower("word", "dw", "sword", 2)
  6433. .CasesLower("dword", "dd", "sdword", 4)
  6434. .CasesLower("fword", "df", 6)
  6435. .CasesLower("qword", "dq", "sqword", 8)
  6436. .CaseLower("real4", 4)
  6437. .CaseLower("real8", 8)
  6438. .CaseLower("real10", 10)
  6439. .Default(0);
  6440. if (Size) {
  6441. Info.Name = Name;
  6442. Info.ElementSize = Size;
  6443. Info.Length = 1;
  6444. Info.Size = Size;
  6445. return false;
  6446. }
  6447. auto StructIt = Structs.find(Name.lower());
  6448. if (StructIt != Structs.end()) {
  6449. const StructInfo &Structure = StructIt->second;
  6450. Info.Name = Name;
  6451. Info.ElementSize = Structure.Size;
  6452. Info.Length = 1;
  6453. Info.Size = Structure.Size;
  6454. return false;
  6455. }
  6456. return true;
  6457. }
  6458. bool MasmParser::parseMSInlineAsm(
  6459. std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs,
  6460. SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
  6461. SmallVectorImpl<std::string> &Constraints,
  6462. SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
  6463. const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) {
  6464. SmallVector<void *, 4> InputDecls;
  6465. SmallVector<void *, 4> OutputDecls;
  6466. SmallVector<bool, 4> InputDeclsAddressOf;
  6467. SmallVector<bool, 4> OutputDeclsAddressOf;
  6468. SmallVector<std::string, 4> InputConstraints;
  6469. SmallVector<std::string, 4> OutputConstraints;
  6470. SmallVector<unsigned, 4> ClobberRegs;
  6471. SmallVector<AsmRewrite, 4> AsmStrRewrites;
  6472. // Prime the lexer.
  6473. Lex();
  6474. // While we have input, parse each statement.
  6475. unsigned InputIdx = 0;
  6476. unsigned OutputIdx = 0;
  6477. while (getLexer().isNot(AsmToken::Eof)) {
  6478. // Parse curly braces marking block start/end.
  6479. if (parseCurlyBlockScope(AsmStrRewrites))
  6480. continue;
  6481. ParseStatementInfo Info(&AsmStrRewrites);
  6482. bool StatementErr = parseStatement(Info, &SI);
  6483. if (StatementErr || Info.ParseError) {
  6484. // Emit pending errors if any exist.
  6485. printPendingErrors();
  6486. return true;
  6487. }
  6488. // No pending error should exist here.
  6489. assert(!hasPendingError() && "unexpected error from parseStatement");
  6490. if (Info.Opcode == ~0U)
  6491. continue;
  6492. const MCInstrDesc &Desc = MII->get(Info.Opcode);
  6493. // Build the list of clobbers, outputs and inputs.
  6494. for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
  6495. MCParsedAsmOperand &Operand = *Info.ParsedOperands[i];
  6496. // Register operand.
  6497. if (Operand.isReg() && !Operand.needAddressOf() &&
  6498. !getTargetParser().OmitRegisterFromClobberLists(Operand.getReg())) {
  6499. unsigned NumDefs = Desc.getNumDefs();
  6500. // Clobber.
  6501. if (NumDefs && Operand.getMCOperandNum() < NumDefs)
  6502. ClobberRegs.push_back(Operand.getReg());
  6503. continue;
  6504. }
  6505. // Expr/Input or Output.
  6506. StringRef SymName = Operand.getSymName();
  6507. if (SymName.empty())
  6508. continue;
  6509. void *OpDecl = Operand.getOpDecl();
  6510. if (!OpDecl)
  6511. continue;
  6512. StringRef Constraint = Operand.getConstraint();
  6513. if (Operand.isImm()) {
  6514. // Offset as immediate.
  6515. if (Operand.isOffsetOfLocal())
  6516. Constraint = "r";
  6517. else
  6518. Constraint = "i";
  6519. }
  6520. bool isOutput = (i == 1) && Desc.mayStore();
  6521. SMLoc Start = SMLoc::getFromPointer(SymName.data());
  6522. if (isOutput) {
  6523. ++InputIdx;
  6524. OutputDecls.push_back(OpDecl);
  6525. OutputDeclsAddressOf.push_back(Operand.needAddressOf());
  6526. OutputConstraints.push_back(("=" + Constraint).str());
  6527. AsmStrRewrites.emplace_back(AOK_Output, Start, SymName.size());
  6528. } else {
  6529. InputDecls.push_back(OpDecl);
  6530. InputDeclsAddressOf.push_back(Operand.needAddressOf());
  6531. InputConstraints.push_back(Constraint.str());
  6532. if (Desc.operands()[i - 1].isBranchTarget())
  6533. AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size());
  6534. else
  6535. AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size());
  6536. }
  6537. }
  6538. // Consider implicit defs to be clobbers. Think of cpuid and push.
  6539. llvm::append_range(ClobberRegs, Desc.implicit_defs());
  6540. }
  6541. // Set the number of Outputs and Inputs.
  6542. NumOutputs = OutputDecls.size();
  6543. NumInputs = InputDecls.size();
  6544. // Set the unique clobbers.
  6545. array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
  6546. ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
  6547. ClobberRegs.end());
  6548. Clobbers.assign(ClobberRegs.size(), std::string());
  6549. for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
  6550. raw_string_ostream OS(Clobbers[I]);
  6551. IP->printRegName(OS, ClobberRegs[I]);
  6552. }
  6553. // Merge the various outputs and inputs. Output are expected first.
  6554. if (NumOutputs || NumInputs) {
  6555. unsigned NumExprs = NumOutputs + NumInputs;
  6556. OpDecls.resize(NumExprs);
  6557. Constraints.resize(NumExprs);
  6558. for (unsigned i = 0; i < NumOutputs; ++i) {
  6559. OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
  6560. Constraints[i] = OutputConstraints[i];
  6561. }
  6562. for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
  6563. OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
  6564. Constraints[j] = InputConstraints[i];
  6565. }
  6566. }
  6567. // Build the IR assembly string.
  6568. std::string AsmStringIR;
  6569. raw_string_ostream OS(AsmStringIR);
  6570. StringRef ASMString =
  6571. SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer();
  6572. const char *AsmStart = ASMString.begin();
  6573. const char *AsmEnd = ASMString.end();
  6574. array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), rewritesSort);
  6575. for (auto it = AsmStrRewrites.begin(); it != AsmStrRewrites.end(); ++it) {
  6576. const AsmRewrite &AR = *it;
  6577. // Check if this has already been covered by another rewrite...
  6578. if (AR.Done)
  6579. continue;
  6580. AsmRewriteKind Kind = AR.Kind;
  6581. const char *Loc = AR.Loc.getPointer();
  6582. assert(Loc >= AsmStart && "Expected Loc to be at or after Start!");
  6583. // Emit everything up to the immediate/expression.
  6584. if (unsigned Len = Loc - AsmStart)
  6585. OS << StringRef(AsmStart, Len);
  6586. // Skip the original expression.
  6587. if (Kind == AOK_Skip) {
  6588. AsmStart = Loc + AR.Len;
  6589. continue;
  6590. }
  6591. unsigned AdditionalSkip = 0;
  6592. // Rewrite expressions in $N notation.
  6593. switch (Kind) {
  6594. default:
  6595. break;
  6596. case AOK_IntelExpr:
  6597. assert(AR.IntelExp.isValid() && "cannot write invalid intel expression");
  6598. if (AR.IntelExp.NeedBracs)
  6599. OS << "[";
  6600. if (AR.IntelExp.hasBaseReg())
  6601. OS << AR.IntelExp.BaseReg;
  6602. if (AR.IntelExp.hasIndexReg())
  6603. OS << (AR.IntelExp.hasBaseReg() ? " + " : "")
  6604. << AR.IntelExp.IndexReg;
  6605. if (AR.IntelExp.Scale > 1)
  6606. OS << " * $$" << AR.IntelExp.Scale;
  6607. if (AR.IntelExp.hasOffset()) {
  6608. if (AR.IntelExp.hasRegs())
  6609. OS << " + ";
  6610. // Fuse this rewrite with a rewrite of the offset name, if present.
  6611. StringRef OffsetName = AR.IntelExp.OffsetName;
  6612. SMLoc OffsetLoc = SMLoc::getFromPointer(AR.IntelExp.OffsetName.data());
  6613. size_t OffsetLen = OffsetName.size();
  6614. auto rewrite_it = std::find_if(
  6615. it, AsmStrRewrites.end(), [&](const AsmRewrite &FusingAR) {
  6616. return FusingAR.Loc == OffsetLoc && FusingAR.Len == OffsetLen &&
  6617. (FusingAR.Kind == AOK_Input ||
  6618. FusingAR.Kind == AOK_CallInput);
  6619. });
  6620. if (rewrite_it == AsmStrRewrites.end()) {
  6621. OS << "offset " << OffsetName;
  6622. } else if (rewrite_it->Kind == AOK_CallInput) {
  6623. OS << "${" << InputIdx++ << ":P}";
  6624. rewrite_it->Done = true;
  6625. } else {
  6626. OS << '$' << InputIdx++;
  6627. rewrite_it->Done = true;
  6628. }
  6629. }
  6630. if (AR.IntelExp.Imm || AR.IntelExp.emitImm())
  6631. OS << (AR.IntelExp.emitImm() ? "$$" : " + $$") << AR.IntelExp.Imm;
  6632. if (AR.IntelExp.NeedBracs)
  6633. OS << "]";
  6634. break;
  6635. case AOK_Label:
  6636. OS << Ctx.getAsmInfo()->getPrivateLabelPrefix() << AR.Label;
  6637. break;
  6638. case AOK_Input:
  6639. OS << '$' << InputIdx++;
  6640. break;
  6641. case AOK_CallInput:
  6642. OS << "${" << InputIdx++ << ":P}";
  6643. break;
  6644. case AOK_Output:
  6645. OS << '$' << OutputIdx++;
  6646. break;
  6647. case AOK_SizeDirective:
  6648. switch (AR.Val) {
  6649. default: break;
  6650. case 8: OS << "byte ptr "; break;
  6651. case 16: OS << "word ptr "; break;
  6652. case 32: OS << "dword ptr "; break;
  6653. case 64: OS << "qword ptr "; break;
  6654. case 80: OS << "xword ptr "; break;
  6655. case 128: OS << "xmmword ptr "; break;
  6656. case 256: OS << "ymmword ptr "; break;
  6657. }
  6658. break;
  6659. case AOK_Emit:
  6660. OS << ".byte";
  6661. break;
  6662. case AOK_Align: {
  6663. // MS alignment directives are measured in bytes. If the native assembler
  6664. // measures alignment in bytes, we can pass it straight through.
  6665. OS << ".align";
  6666. if (getContext().getAsmInfo()->getAlignmentIsInBytes())
  6667. break;
  6668. // Alignment is in log2 form, so print that instead and skip the original
  6669. // immediate.
  6670. unsigned Val = AR.Val;
  6671. OS << ' ' << Val;
  6672. assert(Val < 10 && "Expected alignment less then 2^10.");
  6673. AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
  6674. break;
  6675. }
  6676. case AOK_EVEN:
  6677. OS << ".even";
  6678. break;
  6679. case AOK_EndOfStatement:
  6680. OS << "\n\t";
  6681. break;
  6682. }
  6683. // Skip the original expression.
  6684. AsmStart = Loc + AR.Len + AdditionalSkip;
  6685. }
  6686. // Emit the remainder of the asm string.
  6687. if (AsmStart != AsmEnd)
  6688. OS << StringRef(AsmStart, AsmEnd - AsmStart);
  6689. AsmString = OS.str();
  6690. return false;
  6691. }
  6692. void MasmParser::initializeBuiltinSymbolMap() {
  6693. // Numeric built-ins (supported in all versions)
  6694. BuiltinSymbolMap["@version"] = BI_VERSION;
  6695. BuiltinSymbolMap["@line"] = BI_LINE;
  6696. // Text built-ins (supported in all versions)
  6697. BuiltinSymbolMap["@date"] = BI_DATE;
  6698. BuiltinSymbolMap["@time"] = BI_TIME;
  6699. BuiltinSymbolMap["@filecur"] = BI_FILECUR;
  6700. BuiltinSymbolMap["@filename"] = BI_FILENAME;
  6701. BuiltinSymbolMap["@curseg"] = BI_CURSEG;
  6702. // Some built-ins exist only for MASM32 (32-bit x86)
  6703. if (getContext().getSubtargetInfo()->getTargetTriple().getArch() ==
  6704. Triple::x86) {
  6705. // Numeric built-ins
  6706. // BuiltinSymbolMap["@cpu"] = BI_CPU;
  6707. // BuiltinSymbolMap["@interface"] = BI_INTERFACE;
  6708. // BuiltinSymbolMap["@wordsize"] = BI_WORDSIZE;
  6709. // BuiltinSymbolMap["@codesize"] = BI_CODESIZE;
  6710. // BuiltinSymbolMap["@datasize"] = BI_DATASIZE;
  6711. // BuiltinSymbolMap["@model"] = BI_MODEL;
  6712. // Text built-ins
  6713. // BuiltinSymbolMap["@code"] = BI_CODE;
  6714. // BuiltinSymbolMap["@data"] = BI_DATA;
  6715. // BuiltinSymbolMap["@fardata?"] = BI_FARDATA;
  6716. // BuiltinSymbolMap["@stack"] = BI_STACK;
  6717. }
  6718. }
  6719. const MCExpr *MasmParser::evaluateBuiltinValue(BuiltinSymbol Symbol,
  6720. SMLoc StartLoc) {
  6721. switch (Symbol) {
  6722. default:
  6723. return nullptr;
  6724. case BI_VERSION:
  6725. // Match a recent version of ML.EXE.
  6726. return MCConstantExpr::create(1427, getContext());
  6727. case BI_LINE: {
  6728. int64_t Line;
  6729. if (ActiveMacros.empty())
  6730. Line = SrcMgr.FindLineNumber(StartLoc, CurBuffer);
  6731. else
  6732. Line = SrcMgr.FindLineNumber(ActiveMacros.front()->InstantiationLoc,
  6733. ActiveMacros.front()->ExitBuffer);
  6734. return MCConstantExpr::create(Line, getContext());
  6735. }
  6736. }
  6737. llvm_unreachable("unhandled built-in symbol");
  6738. }
  6739. std::optional<std::string>
  6740. MasmParser::evaluateBuiltinTextMacro(BuiltinSymbol Symbol, SMLoc StartLoc) {
  6741. switch (Symbol) {
  6742. default:
  6743. return {};
  6744. case BI_DATE: {
  6745. // Current local date, formatted MM/DD/YY
  6746. char TmpBuffer[sizeof("mm/dd/yy")];
  6747. const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%D", &TM);
  6748. return std::string(TmpBuffer, Len);
  6749. }
  6750. case BI_TIME: {
  6751. // Current local time, formatted HH:MM:SS (24-hour clock)
  6752. char TmpBuffer[sizeof("hh:mm:ss")];
  6753. const size_t Len = strftime(TmpBuffer, sizeof(TmpBuffer), "%T", &TM);
  6754. return std::string(TmpBuffer, Len);
  6755. }
  6756. case BI_FILECUR:
  6757. return SrcMgr
  6758. .getMemoryBuffer(
  6759. ActiveMacros.empty() ? CurBuffer : ActiveMacros.front()->ExitBuffer)
  6760. ->getBufferIdentifier()
  6761. .str();
  6762. case BI_FILENAME:
  6763. return sys::path::stem(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())
  6764. ->getBufferIdentifier())
  6765. .upper();
  6766. case BI_CURSEG:
  6767. return getStreamer().getCurrentSectionOnly()->getName().str();
  6768. }
  6769. llvm_unreachable("unhandled built-in symbol");
  6770. }
  6771. /// Create an MCAsmParser instance.
  6772. MCAsmParser *llvm::createMCMasmParser(SourceMgr &SM, MCContext &C,
  6773. MCStreamer &Out, const MCAsmInfo &MAI,
  6774. struct tm TM, unsigned CB) {
  6775. return new MasmParser(SM, C, Out, MAI, TM, CB);
  6776. }