123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574 |
- //===- ASTImporter.cpp - Importing ASTs from other Contexts ---------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the ASTImporter class which imports AST nodes from one
- // context into another context.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/AST/ASTImporter.h"
- #include "clang/AST/ASTImporterLookupTable.h"
- #include "clang/AST/ASTContext.h"
- #include "clang/AST/ASTDiagnostic.h"
- #include "clang/AST/ASTStructuralEquivalence.h"
- #include "clang/AST/Attr.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclAccessPair.h"
- #include "clang/AST/DeclBase.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclFriend.h"
- #include "clang/AST/DeclGroup.h"
- #include "clang/AST/DeclObjC.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/DeclVisitor.h"
- #include "clang/AST/DeclarationName.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/ExprObjC.h"
- #include "clang/AST/ExternalASTSource.h"
- #include "clang/AST/LambdaCapture.h"
- #include "clang/AST/NestedNameSpecifier.h"
- #include "clang/AST/OperationKinds.h"
- #include "clang/AST/Stmt.h"
- #include "clang/AST/StmtCXX.h"
- #include "clang/AST/StmtObjC.h"
- #include "clang/AST/StmtVisitor.h"
- #include "clang/AST/TemplateBase.h"
- #include "clang/AST/TemplateName.h"
- #include "clang/AST/Type.h"
- #include "clang/AST/TypeLoc.h"
- #include "clang/AST/TypeVisitor.h"
- #include "clang/AST/UnresolvedSet.h"
- #include "clang/Basic/ExceptionSpecificationType.h"
- #include "clang/Basic/FileManager.h"
- #include "clang/Basic/IdentifierTable.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/LangOptions.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/SourceManager.h"
- #include "clang/Basic/Specifiers.h"
- #include "llvm/ADT/APSInt.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/None.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/MemoryBuffer.h"
- #include <algorithm>
- #include <cassert>
- #include <cstddef>
- #include <memory>
- #include <type_traits>
- #include <utility>
- namespace clang {
- using llvm::make_error;
- using llvm::Error;
- using llvm::Expected;
- using ExpectedType = llvm::Expected<QualType>;
- using ExpectedStmt = llvm::Expected<Stmt *>;
- using ExpectedExpr = llvm::Expected<Expr *>;
- using ExpectedDecl = llvm::Expected<Decl *>;
- using ExpectedSLoc = llvm::Expected<SourceLocation>;
- std::string ImportError::toString() const {
- // FIXME: Improve error texts.
- switch (Error) {
- case NameConflict:
- return "NameConflict";
- case UnsupportedConstruct:
- return "UnsupportedConstruct";
- case Unknown:
- return "Unknown error";
- }
- llvm_unreachable("Invalid error code.");
- return "Invalid error code.";
- }
- void ImportError::log(raw_ostream &OS) const {
- OS << toString();
- }
- std::error_code ImportError::convertToErrorCode() const {
- llvm_unreachable("Function not implemented.");
- }
- char ImportError::ID;
- template <class T>
- SmallVector<Decl *, 2>
- getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
- SmallVector<Decl *, 2> Redecls;
- for (auto *R : D->getFirstDecl()->redecls()) {
- if (R != D->getFirstDecl())
- Redecls.push_back(R);
- }
- Redecls.push_back(D->getFirstDecl());
- std::reverse(Redecls.begin(), Redecls.end());
- return Redecls;
- }
- SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D) {
- if (auto *FD = dyn_cast<FunctionDecl>(D))
- return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
- if (auto *VD = dyn_cast<VarDecl>(D))
- return getCanonicalForwardRedeclChain<VarDecl>(VD);
- if (auto *TD = dyn_cast<TagDecl>(D))
- return getCanonicalForwardRedeclChain<TagDecl>(TD);
- llvm_unreachable("Bad declaration kind");
- }
- void updateFlags(const Decl *From, Decl *To) {
- // Check if some flags or attrs are new in 'From' and copy into 'To'.
- // FIXME: Other flags or attrs?
- if (From->isUsed(false) && !To->isUsed(false))
- To->setIsUsed();
- }
- class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, ExpectedType>,
- public DeclVisitor<ASTNodeImporter, ExpectedDecl>,
- public StmtVisitor<ASTNodeImporter, ExpectedStmt> {
- ASTImporter &Importer;
- // Use this instead of Importer.importInto .
- template <typename ImportT>
- LLVM_NODISCARD Error importInto(ImportT &To, const ImportT &From) {
- return Importer.importInto(To, From);
- }
- // Use this to import pointers of specific type.
- template <typename ImportT>
- LLVM_NODISCARD Error importInto(ImportT *&To, ImportT *From) {
- auto ToOrErr = Importer.Import(From);
- if (ToOrErr)
- To = cast_or_null<ImportT>(*ToOrErr);
- return ToOrErr.takeError();
- }
- // Call the import function of ASTImporter for a baseclass of type `T` and
- // cast the return value to `T`.
- template <typename T>
- Expected<T *> import(T *From) {
- auto ToOrErr = Importer.Import(From);
- if (!ToOrErr)
- return ToOrErr.takeError();
- return cast_or_null<T>(*ToOrErr);
- }
- template <typename T>
- Expected<T *> import(const T *From) {
- return import(const_cast<T *>(From));
- }
- // Call the import function of ASTImporter for type `T`.
- template <typename T>
- Expected<T> import(const T &From) {
- return Importer.Import(From);
- }
- // Import an Optional<T> by importing the contained T, if any.
- template<typename T>
- Expected<Optional<T>> import(Optional<T> From) {
- if (!From)
- return Optional<T>();
- return import(*From);
- }
- template <class T>
- Expected<std::tuple<T>>
- importSeq(const T &From) {
- Expected<T> ToOrErr = import(From);
- if (!ToOrErr)
- return ToOrErr.takeError();
- return std::make_tuple<T>(std::move(*ToOrErr));
- }
- // Import multiple objects with a single function call.
- // This should work for every type for which a variant of `import` exists.
- // The arguments are processed from left to right and import is stopped on
- // first error.
- template <class THead, class... TTail>
- Expected<std::tuple<THead, TTail...>>
- importSeq(const THead &FromHead, const TTail &...FromTail) {
- Expected<std::tuple<THead>> ToHeadOrErr = importSeq(FromHead);
- if (!ToHeadOrErr)
- return ToHeadOrErr.takeError();
- Expected<std::tuple<TTail...>> ToTailOrErr = importSeq(FromTail...);
- if (!ToTailOrErr)
- return ToTailOrErr.takeError();
- return std::tuple_cat(*ToHeadOrErr, *ToTailOrErr);
- }
- // Wrapper for an overload set.
- template <typename ToDeclT> struct CallOverloadedCreateFun {
- template <typename... Args>
- auto operator()(Args &&... args)
- -> decltype(ToDeclT::Create(std::forward<Args>(args)...)) {
- return ToDeclT::Create(std::forward<Args>(args)...);
- }
- };
- // Always use these functions to create a Decl during import. There are
- // certain tasks which must be done after the Decl was created, e.g. we
- // must immediately register that as an imported Decl. The parameter `ToD`
- // will be set to the newly created Decl or if had been imported before
- // then to the already imported Decl. Returns a bool value set to true if
- // the `FromD` had been imported before.
- template <typename ToDeclT, typename FromDeclT, typename... Args>
- LLVM_NODISCARD bool GetImportedOrCreateDecl(ToDeclT *&ToD, FromDeclT *FromD,
- Args &&... args) {
- // There may be several overloads of ToDeclT::Create. We must make sure
- // to call the one which would be chosen by the arguments, thus we use a
- // wrapper for the overload set.
- CallOverloadedCreateFun<ToDeclT> OC;
- return GetImportedOrCreateSpecialDecl(ToD, OC, FromD,
- std::forward<Args>(args)...);
- }
- // Use this overload if a special Type is needed to be created. E.g if we
- // want to create a `TypeAliasDecl` and assign that to a `TypedefNameDecl`
- // then:
- // TypedefNameDecl *ToTypedef;
- // GetImportedOrCreateDecl<TypeAliasDecl>(ToTypedef, FromD, ...);
- template <typename NewDeclT, typename ToDeclT, typename FromDeclT,
- typename... Args>
- LLVM_NODISCARD bool GetImportedOrCreateDecl(ToDeclT *&ToD, FromDeclT *FromD,
- Args &&... args) {
- CallOverloadedCreateFun<NewDeclT> OC;
- return GetImportedOrCreateSpecialDecl(ToD, OC, FromD,
- std::forward<Args>(args)...);
- }
- // Use this version if a special create function must be
- // used, e.g. CXXRecordDecl::CreateLambda .
- template <typename ToDeclT, typename CreateFunT, typename FromDeclT,
- typename... Args>
- LLVM_NODISCARD bool
- GetImportedOrCreateSpecialDecl(ToDeclT *&ToD, CreateFunT CreateFun,
- FromDeclT *FromD, Args &&... args) {
- // FIXME: This code is needed later.
- //if (Importer.getImportDeclErrorIfAny(FromD)) {
- // ToD = nullptr;
- // return true; // Already imported but with error.
- //}
- ToD = cast_or_null<ToDeclT>(Importer.GetAlreadyImportedOrNull(FromD));
- if (ToD)
- return true; // Already imported.
- ToD = CreateFun(std::forward<Args>(args)...);
- // Keep track of imported Decls.
- Importer.RegisterImportedDecl(FromD, ToD);
- InitializeImportedDecl(FromD, ToD);
- return false; // A new Decl is created.
- }
- void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
- ToD->IdentifierNamespace = FromD->IdentifierNamespace;
- if (FromD->hasAttrs())
- for (const Attr *FromAttr : FromD->getAttrs()) {
- // FIXME: Return of the error here is not possible until store of
- // import errors is implemented.
- auto ToAttrOrErr = import(FromAttr);
- if (ToAttrOrErr)
- ToD->addAttr(*ToAttrOrErr);
- else
- llvm::consumeError(ToAttrOrErr.takeError());
- }
- if (FromD->isUsed())
- ToD->setIsUsed();
- if (FromD->isImplicit())
- ToD->setImplicit();
- }
- // Check if we have found an existing definition. Returns with that
- // definition if yes, otherwise returns null.
- Decl *FindAndMapDefinition(FunctionDecl *D, FunctionDecl *FoundFunction) {
- const FunctionDecl *Definition = nullptr;
- if (D->doesThisDeclarationHaveABody() &&
- FoundFunction->hasBody(Definition))
- return Importer.MapImported(D, const_cast<FunctionDecl *>(Definition));
- return nullptr;
- }
- public:
- explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
- using TypeVisitor<ASTNodeImporter, ExpectedType>::Visit;
- using DeclVisitor<ASTNodeImporter, ExpectedDecl>::Visit;
- using StmtVisitor<ASTNodeImporter, ExpectedStmt>::Visit;
- // Importing types
- ExpectedType VisitType(const Type *T);
- ExpectedType VisitAtomicType(const AtomicType *T);
- ExpectedType VisitBuiltinType(const BuiltinType *T);
- ExpectedType VisitDecayedType(const DecayedType *T);
- ExpectedType VisitComplexType(const ComplexType *T);
- ExpectedType VisitPointerType(const PointerType *T);
- ExpectedType VisitBlockPointerType(const BlockPointerType *T);
- ExpectedType VisitLValueReferenceType(const LValueReferenceType *T);
- ExpectedType VisitRValueReferenceType(const RValueReferenceType *T);
- ExpectedType VisitMemberPointerType(const MemberPointerType *T);
- ExpectedType VisitConstantArrayType(const ConstantArrayType *T);
- ExpectedType VisitIncompleteArrayType(const IncompleteArrayType *T);
- ExpectedType VisitVariableArrayType(const VariableArrayType *T);
- ExpectedType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
- // FIXME: DependentSizedExtVectorType
- ExpectedType VisitVectorType(const VectorType *T);
- ExpectedType VisitExtVectorType(const ExtVectorType *T);
- ExpectedType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
- ExpectedType VisitFunctionProtoType(const FunctionProtoType *T);
- ExpectedType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
- ExpectedType VisitParenType(const ParenType *T);
- ExpectedType VisitTypedefType(const TypedefType *T);
- ExpectedType VisitTypeOfExprType(const TypeOfExprType *T);
- // FIXME: DependentTypeOfExprType
- ExpectedType VisitTypeOfType(const TypeOfType *T);
- ExpectedType VisitDecltypeType(const DecltypeType *T);
- ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
- ExpectedType VisitAutoType(const AutoType *T);
- ExpectedType VisitInjectedClassNameType(const InjectedClassNameType *T);
- // FIXME: DependentDecltypeType
- ExpectedType VisitRecordType(const RecordType *T);
- ExpectedType VisitEnumType(const EnumType *T);
- ExpectedType VisitAttributedType(const AttributedType *T);
- ExpectedType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
- ExpectedType VisitSubstTemplateTypeParmType(
- const SubstTemplateTypeParmType *T);
- ExpectedType VisitTemplateSpecializationType(
- const TemplateSpecializationType *T);
- ExpectedType VisitElaboratedType(const ElaboratedType *T);
- ExpectedType VisitDependentNameType(const DependentNameType *T);
- ExpectedType VisitPackExpansionType(const PackExpansionType *T);
- ExpectedType VisitDependentTemplateSpecializationType(
- const DependentTemplateSpecializationType *T);
- ExpectedType VisitObjCInterfaceType(const ObjCInterfaceType *T);
- ExpectedType VisitObjCObjectType(const ObjCObjectType *T);
- ExpectedType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
- // Importing declarations
- Error ImportDeclParts(
- NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
- DeclarationName &Name, NamedDecl *&ToD, SourceLocation &Loc);
- Error ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
- Error ImportDeclarationNameLoc(
- const DeclarationNameInfo &From, DeclarationNameInfo &To);
- Error ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
- Error ImportDeclContext(
- Decl *From, DeclContext *&ToDC, DeclContext *&ToLexicalDC);
- Error ImportImplicitMethods(const CXXRecordDecl *From, CXXRecordDecl *To);
- Expected<CXXCastPath> ImportCastPath(CastExpr *E);
- using Designator = DesignatedInitExpr::Designator;
- /// What we should import from the definition.
- enum ImportDefinitionKind {
- /// Import the default subset of the definition, which might be
- /// nothing (if minimal import is set) or might be everything (if minimal
- /// import is not set).
- IDK_Default,
- /// Import everything.
- IDK_Everything,
- /// Import only the bare bones needed to establish a valid
- /// DeclContext.
- IDK_Basic
- };
- bool shouldForceImportDeclContext(ImportDefinitionKind IDK) {
- return IDK == IDK_Everything ||
- (IDK == IDK_Default && !Importer.isMinimalImport());
- }
- Error ImportInitializer(VarDecl *From, VarDecl *To);
- Error ImportDefinition(
- RecordDecl *From, RecordDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- Error ImportDefinition(
- EnumDecl *From, EnumDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- Error ImportDefinition(
- ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- Error ImportDefinition(
- ObjCProtocolDecl *From, ObjCProtocolDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- Error ImportTemplateArguments(
- const TemplateArgument *FromArgs, unsigned NumFromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs);
- Expected<TemplateArgument>
- ImportTemplateArgument(const TemplateArgument &From);
- template <typename InContainerTy>
- Error ImportTemplateArgumentListInfo(
- const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo);
- template<typename InContainerTy>
- Error ImportTemplateArgumentListInfo(
- SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
- const InContainerTy &Container, TemplateArgumentListInfo &Result);
- using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
- using FunctionTemplateAndArgsTy =
- std::tuple<FunctionTemplateDecl *, TemplateArgsTy>;
- Expected<FunctionTemplateAndArgsTy>
- ImportFunctionTemplateWithTemplateArgsFromSpecialization(
- FunctionDecl *FromFD);
- Error ImportTemplateParameterLists(const DeclaratorDecl *FromD,
- DeclaratorDecl *ToD);
- Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
- Error ImportFunctionDeclBody(FunctionDecl *FromFD, FunctionDecl *ToFD);
- template <typename T>
- bool hasSameVisibilityContext(T *Found, T *From);
- bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
- bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
- bool Complain = true);
- bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
- bool Complain = true);
- bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
- bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
- bool IsStructuralMatch(FunctionTemplateDecl *From,
- FunctionTemplateDecl *To);
- bool IsStructuralMatch(FunctionDecl *From, FunctionDecl *To);
- bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
- bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
- ExpectedDecl VisitDecl(Decl *D);
- ExpectedDecl VisitImportDecl(ImportDecl *D);
- ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
- ExpectedDecl VisitAccessSpecDecl(AccessSpecDecl *D);
- ExpectedDecl VisitStaticAssertDecl(StaticAssertDecl *D);
- ExpectedDecl VisitTranslationUnitDecl(TranslationUnitDecl *D);
- ExpectedDecl VisitNamespaceDecl(NamespaceDecl *D);
- ExpectedDecl VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- ExpectedDecl VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
- ExpectedDecl VisitTypedefDecl(TypedefDecl *D);
- ExpectedDecl VisitTypeAliasDecl(TypeAliasDecl *D);
- ExpectedDecl VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
- ExpectedDecl VisitLabelDecl(LabelDecl *D);
- ExpectedDecl VisitEnumDecl(EnumDecl *D);
- ExpectedDecl VisitRecordDecl(RecordDecl *D);
- ExpectedDecl VisitEnumConstantDecl(EnumConstantDecl *D);
- ExpectedDecl VisitFunctionDecl(FunctionDecl *D);
- ExpectedDecl VisitCXXMethodDecl(CXXMethodDecl *D);
- ExpectedDecl VisitCXXConstructorDecl(CXXConstructorDecl *D);
- ExpectedDecl VisitCXXDestructorDecl(CXXDestructorDecl *D);
- ExpectedDecl VisitCXXConversionDecl(CXXConversionDecl *D);
- ExpectedDecl VisitFieldDecl(FieldDecl *D);
- ExpectedDecl VisitIndirectFieldDecl(IndirectFieldDecl *D);
- ExpectedDecl VisitFriendDecl(FriendDecl *D);
- ExpectedDecl VisitObjCIvarDecl(ObjCIvarDecl *D);
- ExpectedDecl VisitVarDecl(VarDecl *D);
- ExpectedDecl VisitImplicitParamDecl(ImplicitParamDecl *D);
- ExpectedDecl VisitParmVarDecl(ParmVarDecl *D);
- ExpectedDecl VisitObjCMethodDecl(ObjCMethodDecl *D);
- ExpectedDecl VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
- ExpectedDecl VisitObjCCategoryDecl(ObjCCategoryDecl *D);
- ExpectedDecl VisitObjCProtocolDecl(ObjCProtocolDecl *D);
- ExpectedDecl VisitLinkageSpecDecl(LinkageSpecDecl *D);
- ExpectedDecl VisitUsingDecl(UsingDecl *D);
- ExpectedDecl VisitUsingShadowDecl(UsingShadowDecl *D);
- ExpectedDecl VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
- Expected<ObjCTypeParamList *>
- ImportObjCTypeParamList(ObjCTypeParamList *list);
- ExpectedDecl VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- ExpectedDecl VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
- ExpectedDecl VisitObjCImplementationDecl(ObjCImplementationDecl *D);
- ExpectedDecl VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- ExpectedDecl VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- ExpectedDecl VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- ExpectedDecl VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- ExpectedDecl VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- ExpectedDecl VisitClassTemplateDecl(ClassTemplateDecl *D);
- ExpectedDecl VisitClassTemplateSpecializationDecl(
- ClassTemplateSpecializationDecl *D);
- ExpectedDecl VisitVarTemplateDecl(VarTemplateDecl *D);
- ExpectedDecl VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
- ExpectedDecl VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- // Importing statements
- ExpectedStmt VisitStmt(Stmt *S);
- ExpectedStmt VisitGCCAsmStmt(GCCAsmStmt *S);
- ExpectedStmt VisitDeclStmt(DeclStmt *S);
- ExpectedStmt VisitNullStmt(NullStmt *S);
- ExpectedStmt VisitCompoundStmt(CompoundStmt *S);
- ExpectedStmt VisitCaseStmt(CaseStmt *S);
- ExpectedStmt VisitDefaultStmt(DefaultStmt *S);
- ExpectedStmt VisitLabelStmt(LabelStmt *S);
- ExpectedStmt VisitAttributedStmt(AttributedStmt *S);
- ExpectedStmt VisitIfStmt(IfStmt *S);
- ExpectedStmt VisitSwitchStmt(SwitchStmt *S);
- ExpectedStmt VisitWhileStmt(WhileStmt *S);
- ExpectedStmt VisitDoStmt(DoStmt *S);
- ExpectedStmt VisitForStmt(ForStmt *S);
- ExpectedStmt VisitGotoStmt(GotoStmt *S);
- ExpectedStmt VisitIndirectGotoStmt(IndirectGotoStmt *S);
- ExpectedStmt VisitContinueStmt(ContinueStmt *S);
- ExpectedStmt VisitBreakStmt(BreakStmt *S);
- ExpectedStmt VisitReturnStmt(ReturnStmt *S);
- // FIXME: MSAsmStmt
- // FIXME: SEHExceptStmt
- // FIXME: SEHFinallyStmt
- // FIXME: SEHTryStmt
- // FIXME: SEHLeaveStmt
- // FIXME: CapturedStmt
- ExpectedStmt VisitCXXCatchStmt(CXXCatchStmt *S);
- ExpectedStmt VisitCXXTryStmt(CXXTryStmt *S);
- ExpectedStmt VisitCXXForRangeStmt(CXXForRangeStmt *S);
- // FIXME: MSDependentExistsStmt
- ExpectedStmt VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
- ExpectedStmt VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
- ExpectedStmt VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S);
- ExpectedStmt VisitObjCAtTryStmt(ObjCAtTryStmt *S);
- ExpectedStmt VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
- ExpectedStmt VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
- ExpectedStmt VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
- // Importing expressions
- ExpectedStmt VisitExpr(Expr *E);
- ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
- ExpectedStmt VisitChooseExpr(ChooseExpr *E);
- ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
- ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
- ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
- ExpectedStmt VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
- ExpectedStmt VisitDesignatedInitExpr(DesignatedInitExpr *E);
- ExpectedStmt VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
- ExpectedStmt VisitIntegerLiteral(IntegerLiteral *E);
- ExpectedStmt VisitFloatingLiteral(FloatingLiteral *E);
- ExpectedStmt VisitImaginaryLiteral(ImaginaryLiteral *E);
- ExpectedStmt VisitCharacterLiteral(CharacterLiteral *E);
- ExpectedStmt VisitStringLiteral(StringLiteral *E);
- ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
- ExpectedStmt VisitAtomicExpr(AtomicExpr *E);
- ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E);
- ExpectedStmt VisitConstantExpr(ConstantExpr *E);
- ExpectedStmt VisitParenExpr(ParenExpr *E);
- ExpectedStmt VisitParenListExpr(ParenListExpr *E);
- ExpectedStmt VisitStmtExpr(StmtExpr *E);
- ExpectedStmt VisitUnaryOperator(UnaryOperator *E);
- ExpectedStmt VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
- ExpectedStmt VisitBinaryOperator(BinaryOperator *E);
- ExpectedStmt VisitConditionalOperator(ConditionalOperator *E);
- ExpectedStmt VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
- ExpectedStmt VisitOpaqueValueExpr(OpaqueValueExpr *E);
- ExpectedStmt VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
- ExpectedStmt VisitExpressionTraitExpr(ExpressionTraitExpr *E);
- ExpectedStmt VisitArraySubscriptExpr(ArraySubscriptExpr *E);
- ExpectedStmt VisitCompoundAssignOperator(CompoundAssignOperator *E);
- ExpectedStmt VisitImplicitCastExpr(ImplicitCastExpr *E);
- ExpectedStmt VisitExplicitCastExpr(ExplicitCastExpr *E);
- ExpectedStmt VisitOffsetOfExpr(OffsetOfExpr *OE);
- ExpectedStmt VisitCXXThrowExpr(CXXThrowExpr *E);
- ExpectedStmt VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
- ExpectedStmt VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
- ExpectedStmt VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
- ExpectedStmt VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
- ExpectedStmt VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
- ExpectedStmt VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
- ExpectedStmt VisitPackExpansionExpr(PackExpansionExpr *E);
- ExpectedStmt VisitSizeOfPackExpr(SizeOfPackExpr *E);
- ExpectedStmt VisitCXXNewExpr(CXXNewExpr *E);
- ExpectedStmt VisitCXXDeleteExpr(CXXDeleteExpr *E);
- ExpectedStmt VisitCXXConstructExpr(CXXConstructExpr *E);
- ExpectedStmt VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
- ExpectedStmt VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
- ExpectedStmt VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
- ExpectedStmt VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
- ExpectedStmt VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
- ExpectedStmt VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
- ExpectedStmt VisitExprWithCleanups(ExprWithCleanups *E);
- ExpectedStmt VisitCXXThisExpr(CXXThisExpr *E);
- ExpectedStmt VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
- ExpectedStmt VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
- ExpectedStmt VisitMemberExpr(MemberExpr *E);
- ExpectedStmt VisitCallExpr(CallExpr *E);
- ExpectedStmt VisitLambdaExpr(LambdaExpr *LE);
- ExpectedStmt VisitInitListExpr(InitListExpr *E);
- ExpectedStmt VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
- ExpectedStmt VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E);
- ExpectedStmt VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
- ExpectedStmt VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
- ExpectedStmt VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
- ExpectedStmt VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
- ExpectedStmt VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
- ExpectedStmt VisitTypeTraitExpr(TypeTraitExpr *E);
- ExpectedStmt VisitCXXTypeidExpr(CXXTypeidExpr *E);
- template<typename IIter, typename OIter>
- Error ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
- using ItemT = typename std::remove_reference<decltype(*Obegin)>::type;
- for (; Ibegin != Iend; ++Ibegin, ++Obegin) {
- Expected<ItemT> ToOrErr = import(*Ibegin);
- if (!ToOrErr)
- return ToOrErr.takeError();
- *Obegin = *ToOrErr;
- }
- return Error::success();
- }
- // Import every item from a container structure into an output container.
- // If error occurs, stops at first error and returns the error.
- // The output container should have space for all needed elements (it is not
- // expanded, new items are put into from the beginning).
- template<typename InContainerTy, typename OutContainerTy>
- Error ImportContainerChecked(
- const InContainerTy &InContainer, OutContainerTy &OutContainer) {
- return ImportArrayChecked(
- InContainer.begin(), InContainer.end(), OutContainer.begin());
- }
- template<typename InContainerTy, typename OIter>
- Error ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
- return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin);
- }
- void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
- Expected<FunctionDecl *> FindFunctionTemplateSpecialization(
- FunctionDecl *FromFD);
- };
- template <typename InContainerTy>
- Error ASTNodeImporter::ImportTemplateArgumentListInfo(
- SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
- const InContainerTy &Container, TemplateArgumentListInfo &Result) {
- auto ToLAngleLocOrErr = import(FromLAngleLoc);
- if (!ToLAngleLocOrErr)
- return ToLAngleLocOrErr.takeError();
- auto ToRAngleLocOrErr = import(FromRAngleLoc);
- if (!ToRAngleLocOrErr)
- return ToRAngleLocOrErr.takeError();
- TemplateArgumentListInfo ToTAInfo(*ToLAngleLocOrErr, *ToRAngleLocOrErr);
- if (auto Err = ImportTemplateArgumentListInfo(Container, ToTAInfo))
- return Err;
- Result = ToTAInfo;
- return Error::success();
- }
- template <>
- Error ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>(
- const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) {
- return ImportTemplateArgumentListInfo(
- From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result);
- }
- template <>
- Error ASTNodeImporter::ImportTemplateArgumentListInfo<
- ASTTemplateArgumentListInfo>(
- const ASTTemplateArgumentListInfo &From,
- TemplateArgumentListInfo &Result) {
- return ImportTemplateArgumentListInfo(
- From.LAngleLoc, From.RAngleLoc, From.arguments(), Result);
- }
- Expected<ASTNodeImporter::FunctionTemplateAndArgsTy>
- ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
- FunctionDecl *FromFD) {
- assert(FromFD->getTemplatedKind() ==
- FunctionDecl::TK_FunctionTemplateSpecialization);
- FunctionTemplateAndArgsTy Result;
- auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
- if (Error Err = importInto(std::get<0>(Result), FTSInfo->getTemplate()))
- return std::move(Err);
- // Import template arguments.
- auto TemplArgs = FTSInfo->TemplateArguments->asArray();
- if (Error Err = ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
- std::get<1>(Result)))
- return std::move(Err);
- return Result;
- }
- template <>
- Expected<TemplateParameterList *>
- ASTNodeImporter::import(TemplateParameterList *From) {
- SmallVector<NamedDecl *, 4> To(From->size());
- if (Error Err = ImportContainerChecked(*From, To))
- return std::move(Err);
- ExpectedExpr ToRequiresClause = import(From->getRequiresClause());
- if (!ToRequiresClause)
- return ToRequiresClause.takeError();
- auto ToTemplateLocOrErr = import(From->getTemplateLoc());
- if (!ToTemplateLocOrErr)
- return ToTemplateLocOrErr.takeError();
- auto ToLAngleLocOrErr = import(From->getLAngleLoc());
- if (!ToLAngleLocOrErr)
- return ToLAngleLocOrErr.takeError();
- auto ToRAngleLocOrErr = import(From->getRAngleLoc());
- if (!ToRAngleLocOrErr)
- return ToRAngleLocOrErr.takeError();
- return TemplateParameterList::Create(
- Importer.getToContext(),
- *ToTemplateLocOrErr,
- *ToLAngleLocOrErr,
- To,
- *ToRAngleLocOrErr,
- *ToRequiresClause);
- }
- template <>
- Expected<TemplateArgument>
- ASTNodeImporter::import(const TemplateArgument &From) {
- switch (From.getKind()) {
- case TemplateArgument::Null:
- return TemplateArgument();
- case TemplateArgument::Type: {
- ExpectedType ToTypeOrErr = import(From.getAsType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- return TemplateArgument(*ToTypeOrErr);
- }
- case TemplateArgument::Integral: {
- ExpectedType ToTypeOrErr = import(From.getIntegralType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- return TemplateArgument(From, *ToTypeOrErr);
- }
- case TemplateArgument::Declaration: {
- Expected<ValueDecl *> ToOrErr = import(From.getAsDecl());
- if (!ToOrErr)
- return ToOrErr.takeError();
- ExpectedType ToTypeOrErr = import(From.getParamTypeForDecl());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- return TemplateArgument(*ToOrErr, *ToTypeOrErr);
- }
- case TemplateArgument::NullPtr: {
- ExpectedType ToTypeOrErr = import(From.getNullPtrType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- return TemplateArgument(*ToTypeOrErr, /*isNullPtr*/true);
- }
- case TemplateArgument::Template: {
- Expected<TemplateName> ToTemplateOrErr = import(From.getAsTemplate());
- if (!ToTemplateOrErr)
- return ToTemplateOrErr.takeError();
- return TemplateArgument(*ToTemplateOrErr);
- }
- case TemplateArgument::TemplateExpansion: {
- Expected<TemplateName> ToTemplateOrErr =
- import(From.getAsTemplateOrTemplatePattern());
- if (!ToTemplateOrErr)
- return ToTemplateOrErr.takeError();
- return TemplateArgument(
- *ToTemplateOrErr, From.getNumTemplateExpansions());
- }
- case TemplateArgument::Expression:
- if (ExpectedExpr ToExpr = import(From.getAsExpr()))
- return TemplateArgument(*ToExpr);
- else
- return ToExpr.takeError();
- case TemplateArgument::Pack: {
- SmallVector<TemplateArgument, 2> ToPack;
- ToPack.reserve(From.pack_size());
- if (Error Err = ImportTemplateArguments(
- From.pack_begin(), From.pack_size(), ToPack))
- return std::move(Err);
- return TemplateArgument(
- llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
- }
- }
- llvm_unreachable("Invalid template argument kind");
- }
- template <>
- Expected<TemplateArgumentLoc>
- ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) {
- Expected<TemplateArgument> ArgOrErr = import(TALoc.getArgument());
- if (!ArgOrErr)
- return ArgOrErr.takeError();
- TemplateArgument Arg = *ArgOrErr;
- TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
- TemplateArgumentLocInfo ToInfo;
- if (Arg.getKind() == TemplateArgument::Expression) {
- ExpectedExpr E = import(FromInfo.getAsExpr());
- if (!E)
- return E.takeError();
- ToInfo = TemplateArgumentLocInfo(*E);
- } else if (Arg.getKind() == TemplateArgument::Type) {
- if (auto TSIOrErr = import(FromInfo.getAsTypeSourceInfo()))
- ToInfo = TemplateArgumentLocInfo(*TSIOrErr);
- else
- return TSIOrErr.takeError();
- } else {
- auto ToTemplateQualifierLocOrErr =
- import(FromInfo.getTemplateQualifierLoc());
- if (!ToTemplateQualifierLocOrErr)
- return ToTemplateQualifierLocOrErr.takeError();
- auto ToTemplateNameLocOrErr = import(FromInfo.getTemplateNameLoc());
- if (!ToTemplateNameLocOrErr)
- return ToTemplateNameLocOrErr.takeError();
- auto ToTemplateEllipsisLocOrErr =
- import(FromInfo.getTemplateEllipsisLoc());
- if (!ToTemplateEllipsisLocOrErr)
- return ToTemplateEllipsisLocOrErr.takeError();
- ToInfo = TemplateArgumentLocInfo(
- *ToTemplateQualifierLocOrErr,
- *ToTemplateNameLocOrErr,
- *ToTemplateEllipsisLocOrErr);
- }
- return TemplateArgumentLoc(Arg, ToInfo);
- }
- template <>
- Expected<DeclGroupRef> ASTNodeImporter::import(const DeclGroupRef &DG) {
- if (DG.isNull())
- return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0);
- size_t NumDecls = DG.end() - DG.begin();
- SmallVector<Decl *, 1> ToDecls;
- ToDecls.reserve(NumDecls);
- for (Decl *FromD : DG) {
- if (auto ToDOrErr = import(FromD))
- ToDecls.push_back(*ToDOrErr);
- else
- return ToDOrErr.takeError();
- }
- return DeclGroupRef::Create(Importer.getToContext(),
- ToDecls.begin(),
- NumDecls);
- }
- template <>
- Expected<ASTNodeImporter::Designator>
- ASTNodeImporter::import(const Designator &D) {
- if (D.isFieldDesignator()) {
- IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName());
- ExpectedSLoc ToDotLocOrErr = import(D.getDotLoc());
- if (!ToDotLocOrErr)
- return ToDotLocOrErr.takeError();
- ExpectedSLoc ToFieldLocOrErr = import(D.getFieldLoc());
- if (!ToFieldLocOrErr)
- return ToFieldLocOrErr.takeError();
- return Designator(ToFieldName, *ToDotLocOrErr, *ToFieldLocOrErr);
- }
- ExpectedSLoc ToLBracketLocOrErr = import(D.getLBracketLoc());
- if (!ToLBracketLocOrErr)
- return ToLBracketLocOrErr.takeError();
- ExpectedSLoc ToRBracketLocOrErr = import(D.getRBracketLoc());
- if (!ToRBracketLocOrErr)
- return ToRBracketLocOrErr.takeError();
- if (D.isArrayDesignator())
- return Designator(D.getFirstExprIndex(),
- *ToLBracketLocOrErr, *ToRBracketLocOrErr);
- ExpectedSLoc ToEllipsisLocOrErr = import(D.getEllipsisLoc());
- if (!ToEllipsisLocOrErr)
- return ToEllipsisLocOrErr.takeError();
- assert(D.isArrayRangeDesignator());
- return Designator(
- D.getFirstExprIndex(), *ToLBracketLocOrErr, *ToEllipsisLocOrErr,
- *ToRBracketLocOrErr);
- }
- template <>
- Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
- VarDecl *Var = nullptr;
- if (From.capturesVariable()) {
- if (auto VarOrErr = import(From.getCapturedVar()))
- Var = *VarOrErr;
- else
- return VarOrErr.takeError();
- }
- auto LocationOrErr = import(From.getLocation());
- if (!LocationOrErr)
- return LocationOrErr.takeError();
- SourceLocation EllipsisLoc;
- if (From.isPackExpansion())
- if (Error Err = importInto(EllipsisLoc, From.getEllipsisLoc()))
- return std::move(Err);
- return LambdaCapture(
- *LocationOrErr, From.isImplicit(), From.getCaptureKind(), Var,
- EllipsisLoc);
- }
- } // namespace clang
- //----------------------------------------------------------------------------
- // Import Types
- //----------------------------------------------------------------------------
- using namespace clang;
- ExpectedType ASTNodeImporter::VisitType(const Type *T) {
- Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
- << T->getTypeClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
- ExpectedType UnderlyingTypeOrErr = import(T->getValueType());
- if (!UnderlyingTypeOrErr)
- return UnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getAtomicType(*UnderlyingTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
- switch (T->getKind()) {
- #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
- case BuiltinType::Id: \
- return Importer.getToContext().SingletonId;
- #include "clang/Basic/OpenCLImageTypes.def"
- #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
- case BuiltinType::Id: \
- return Importer.getToContext().Id##Ty;
- #include "clang/Basic/OpenCLExtensionTypes.def"
- #define SHARED_SINGLETON_TYPE(Expansion)
- #define BUILTIN_TYPE(Id, SingletonId) \
- case BuiltinType::Id: return Importer.getToContext().SingletonId;
- #include "clang/AST/BuiltinTypes.def"
- // FIXME: for Char16, Char32, and NullPtr, make sure that the "to"
- // context supports C++.
- // FIXME: for ObjCId, ObjCClass, and ObjCSel, make sure that the "to"
- // context supports ObjC.
- case BuiltinType::Char_U:
- // The context we're importing from has an unsigned 'char'. If we're
- // importing into a context with a signed 'char', translate to
- // 'unsigned char' instead.
- if (Importer.getToContext().getLangOpts().CharIsSigned)
- return Importer.getToContext().UnsignedCharTy;
- return Importer.getToContext().CharTy;
- case BuiltinType::Char_S:
- // The context we're importing from has an unsigned 'char'. If we're
- // importing into a context with a signed 'char', translate to
- // 'unsigned char' instead.
- if (!Importer.getToContext().getLangOpts().CharIsSigned)
- return Importer.getToContext().SignedCharTy;
- return Importer.getToContext().CharTy;
- case BuiltinType::WChar_S:
- case BuiltinType::WChar_U:
- // FIXME: If not in C++, shall we translate to the C equivalent of
- // wchar_t?
- return Importer.getToContext().WCharTy;
- }
- llvm_unreachable("Invalid BuiltinType Kind!");
- }
- ExpectedType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
- ExpectedType ToOriginalTypeOrErr = import(T->getOriginalType());
- if (!ToOriginalTypeOrErr)
- return ToOriginalTypeOrErr.takeError();
- return Importer.getToContext().getDecayedType(*ToOriginalTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
- ExpectedType ToElementTypeOrErr = import(T->getElementType());
- if (!ToElementTypeOrErr)
- return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getComplexType(*ToElementTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitPointerType(const PointerType *T) {
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getPointerType(*ToPointeeTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
- // FIXME: Check for blocks support in "to" context.
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getBlockPointerType(*ToPointeeTypeOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
- // FIXME: Check for C++ support in "to" context.
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getLValueReferenceType(*ToPointeeTypeOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
- // FIXME: Check for C++0x support in "to" context.
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getRValueReferenceType(*ToPointeeTypeOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
- // FIXME: Check for C++ support in "to" context.
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- ExpectedType ClassTypeOrErr = import(QualType(T->getClass(), 0));
- if (!ClassTypeOrErr)
- return ClassTypeOrErr.takeError();
- return Importer.getToContext().getMemberPointerType(
- *ToPointeeTypeOrErr, (*ClassTypeOrErr).getTypePtr());
- }
- ExpectedType
- ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
- ExpectedType ToElementTypeOrErr = import(T->getElementType());
- if (!ToElementTypeOrErr)
- return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getConstantArrayType(*ToElementTypeOrErr,
- T->getSize(),
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers());
- }
- ExpectedType
- ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
- ExpectedType ToElementTypeOrErr = import(T->getElementType());
- if (!ToElementTypeOrErr)
- return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getIncompleteArrayType(*ToElementTypeOrErr,
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers());
- }
- ExpectedType
- ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
- QualType ToElementType;
- Expr *ToSizeExpr;
- SourceRange ToBracketsRange;
- if (auto Imp = importSeq(
- T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
- std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
- else
- return Imp.takeError();
- return Importer.getToContext().getVariableArrayType(
- ToElementType, ToSizeExpr, T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers(), ToBracketsRange);
- }
- ExpectedType ASTNodeImporter::VisitDependentSizedArrayType(
- const DependentSizedArrayType *T) {
- QualType ToElementType;
- Expr *ToSizeExpr;
- SourceRange ToBracketsRange;
- if (auto Imp = importSeq(
- T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
- std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
- else
- return Imp.takeError();
- // SizeExpr may be null if size is not specified directly.
- // For example, 'int a[]'.
- return Importer.getToContext().getDependentSizedArrayType(
- ToElementType, ToSizeExpr, T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers(), ToBracketsRange);
- }
- ExpectedType ASTNodeImporter::VisitVectorType(const VectorType *T) {
- ExpectedType ToElementTypeOrErr = import(T->getElementType());
- if (!ToElementTypeOrErr)
- return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getVectorType(*ToElementTypeOrErr,
- T->getNumElements(),
- T->getVectorKind());
- }
- ExpectedType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
- ExpectedType ToElementTypeOrErr = import(T->getElementType());
- if (!ToElementTypeOrErr)
- return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getExtVectorType(*ToElementTypeOrErr,
- T->getNumElements());
- }
- ExpectedType
- ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
- // FIXME: What happens if we're importing a function without a prototype
- // into C++? Should we make it variadic?
- ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
- if (!ToReturnTypeOrErr)
- return ToReturnTypeOrErr.takeError();
- return Importer.getToContext().getFunctionNoProtoType(*ToReturnTypeOrErr,
- T->getExtInfo());
- }
- ExpectedType
- ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
- ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
- if (!ToReturnTypeOrErr)
- return ToReturnTypeOrErr.takeError();
- // Import argument types
- SmallVector<QualType, 4> ArgTypes;
- for (const auto &A : T->param_types()) {
- ExpectedType TyOrErr = import(A);
- if (!TyOrErr)
- return TyOrErr.takeError();
- ArgTypes.push_back(*TyOrErr);
- }
- // Import exception types
- SmallVector<QualType, 4> ExceptionTypes;
- for (const auto &E : T->exceptions()) {
- ExpectedType TyOrErr = import(E);
- if (!TyOrErr)
- return TyOrErr.takeError();
- ExceptionTypes.push_back(*TyOrErr);
- }
- FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
- FunctionProtoType::ExtProtoInfo ToEPI;
- auto Imp = importSeq(
- FromEPI.ExceptionSpec.NoexceptExpr,
- FromEPI.ExceptionSpec.SourceDecl,
- FromEPI.ExceptionSpec.SourceTemplate);
- if (!Imp)
- return Imp.takeError();
- ToEPI.ExtInfo = FromEPI.ExtInfo;
- ToEPI.Variadic = FromEPI.Variadic;
- ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
- ToEPI.TypeQuals = FromEPI.TypeQuals;
- ToEPI.RefQualifier = FromEPI.RefQualifier;
- ToEPI.ExceptionSpec.Type = FromEPI.ExceptionSpec.Type;
- ToEPI.ExceptionSpec.Exceptions = ExceptionTypes;
- std::tie(
- ToEPI.ExceptionSpec.NoexceptExpr,
- ToEPI.ExceptionSpec.SourceDecl,
- ToEPI.ExceptionSpec.SourceTemplate) = *Imp;
- return Importer.getToContext().getFunctionType(
- *ToReturnTypeOrErr, ArgTypes, ToEPI);
- }
- ExpectedType ASTNodeImporter::VisitUnresolvedUsingType(
- const UnresolvedUsingType *T) {
- UnresolvedUsingTypenameDecl *ToD;
- Decl *ToPrevD;
- if (auto Imp = importSeq(T->getDecl(), T->getDecl()->getPreviousDecl()))
- std::tie(ToD, ToPrevD) = *Imp;
- else
- return Imp.takeError();
- return Importer.getToContext().getTypeDeclType(
- ToD, cast_or_null<TypeDecl>(ToPrevD));
- }
- ExpectedType ASTNodeImporter::VisitParenType(const ParenType *T) {
- ExpectedType ToInnerTypeOrErr = import(T->getInnerType());
- if (!ToInnerTypeOrErr)
- return ToInnerTypeOrErr.takeError();
- return Importer.getToContext().getParenType(*ToInnerTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
- Expected<TypedefNameDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- return Importer.getToContext().getTypeDeclType(*ToDeclOrErr);
- }
- ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
- ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
- if (!ToExprOrErr)
- return ToExprOrErr.takeError();
- return Importer.getToContext().getTypeOfExprType(*ToExprOrErr);
- }
- ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
- ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
- if (!ToUnderlyingTypeOrErr)
- return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
- // FIXME: Make sure that the "to" context supports C++0x!
- ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
- if (!ToExprOrErr)
- return ToExprOrErr.takeError();
- ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
- if (!ToUnderlyingTypeOrErr)
- return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getDecltypeType(
- *ToExprOrErr, *ToUnderlyingTypeOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
- ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
- if (!ToBaseTypeOrErr)
- return ToBaseTypeOrErr.takeError();
- ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
- if (!ToUnderlyingTypeOrErr)
- return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getUnaryTransformType(
- *ToBaseTypeOrErr, *ToUnderlyingTypeOrErr, T->getUTTKind());
- }
- ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) {
- // FIXME: Make sure that the "to" context supports C++11!
- ExpectedType ToDeducedTypeOrErr = import(T->getDeducedType());
- if (!ToDeducedTypeOrErr)
- return ToDeducedTypeOrErr.takeError();
- return Importer.getToContext().getAutoType(*ToDeducedTypeOrErr,
- T->getKeyword(),
- /*IsDependent*/false);
- }
- ExpectedType ASTNodeImporter::VisitInjectedClassNameType(
- const InjectedClassNameType *T) {
- Expected<CXXRecordDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- ExpectedType ToInjTypeOrErr = import(T->getInjectedSpecializationType());
- if (!ToInjTypeOrErr)
- return ToInjTypeOrErr.takeError();
- // FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading
- // See comments in InjectedClassNameType definition for details
- // return Importer.getToContext().getInjectedClassNameType(D, InjType);
- enum {
- TypeAlignmentInBits = 4,
- TypeAlignment = 1 << TypeAlignmentInBits
- };
- return QualType(new (Importer.getToContext(), TypeAlignment)
- InjectedClassNameType(*ToDeclOrErr, *ToInjTypeOrErr), 0);
- }
- ExpectedType ASTNodeImporter::VisitRecordType(const RecordType *T) {
- Expected<RecordDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
- }
- ExpectedType ASTNodeImporter::VisitEnumType(const EnumType *T) {
- Expected<EnumDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
- }
- ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
- ExpectedType ToModifiedTypeOrErr = import(T->getModifiedType());
- if (!ToModifiedTypeOrErr)
- return ToModifiedTypeOrErr.takeError();
- ExpectedType ToEquivalentTypeOrErr = import(T->getEquivalentType());
- if (!ToEquivalentTypeOrErr)
- return ToEquivalentTypeOrErr.takeError();
- return Importer.getToContext().getAttributedType(T->getAttrKind(),
- *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitTemplateTypeParmType(
- const TemplateTypeParmType *T) {
- Expected<TemplateTypeParmDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- return Importer.getToContext().getTemplateTypeParmType(
- T->getDepth(), T->getIndex(), T->isParameterPack(), *ToDeclOrErr);
- }
- ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
- const SubstTemplateTypeParmType *T) {
- ExpectedType ReplacedOrErr = import(QualType(T->getReplacedParameter(), 0));
- if (!ReplacedOrErr)
- return ReplacedOrErr.takeError();
- const TemplateTypeParmType *Replaced =
- cast<TemplateTypeParmType>((*ReplacedOrErr).getTypePtr());
- ExpectedType ToReplacementTypeOrErr = import(T->getReplacementType());
- if (!ToReplacementTypeOrErr)
- return ToReplacementTypeOrErr.takeError();
- return Importer.getToContext().getSubstTemplateTypeParmType(
- Replaced, (*ToReplacementTypeOrErr).getCanonicalType());
- }
- ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
- const TemplateSpecializationType *T) {
- auto ToTemplateOrErr = import(T->getTemplateName());
- if (!ToTemplateOrErr)
- return ToTemplateOrErr.takeError();
- SmallVector<TemplateArgument, 2> ToTemplateArgs;
- if (Error Err = ImportTemplateArguments(
- T->getArgs(), T->getNumArgs(), ToTemplateArgs))
- return std::move(Err);
- QualType ToCanonType;
- if (!QualType(T, 0).isCanonical()) {
- QualType FromCanonType
- = Importer.getFromContext().getCanonicalType(QualType(T, 0));
- if (ExpectedType TyOrErr = import(FromCanonType))
- ToCanonType = *TyOrErr;
- else
- return TyOrErr.takeError();
- }
- return Importer.getToContext().getTemplateSpecializationType(*ToTemplateOrErr,
- ToTemplateArgs,
- ToCanonType);
- }
- ExpectedType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
- // Note: the qualifier in an ElaboratedType is optional.
- auto ToQualifierOrErr = import(T->getQualifier());
- if (!ToQualifierOrErr)
- return ToQualifierOrErr.takeError();
- ExpectedType ToNamedTypeOrErr = import(T->getNamedType());
- if (!ToNamedTypeOrErr)
- return ToNamedTypeOrErr.takeError();
- Expected<TagDecl *> ToOwnedTagDeclOrErr = import(T->getOwnedTagDecl());
- if (!ToOwnedTagDeclOrErr)
- return ToOwnedTagDeclOrErr.takeError();
- return Importer.getToContext().getElaboratedType(T->getKeyword(),
- *ToQualifierOrErr,
- *ToNamedTypeOrErr,
- *ToOwnedTagDeclOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
- ExpectedType ToPatternOrErr = import(T->getPattern());
- if (!ToPatternOrErr)
- return ToPatternOrErr.takeError();
- return Importer.getToContext().getPackExpansionType(*ToPatternOrErr,
- T->getNumExpansions());
- }
- ExpectedType ASTNodeImporter::VisitDependentTemplateSpecializationType(
- const DependentTemplateSpecializationType *T) {
- auto ToQualifierOrErr = import(T->getQualifier());
- if (!ToQualifierOrErr)
- return ToQualifierOrErr.takeError();
- IdentifierInfo *ToName = Importer.Import(T->getIdentifier());
- SmallVector<TemplateArgument, 2> ToPack;
- ToPack.reserve(T->getNumArgs());
- if (Error Err = ImportTemplateArguments(
- T->getArgs(), T->getNumArgs(), ToPack))
- return std::move(Err);
- return Importer.getToContext().getDependentTemplateSpecializationType(
- T->getKeyword(), *ToQualifierOrErr, ToName, ToPack);
- }
- ExpectedType
- ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
- auto ToQualifierOrErr = import(T->getQualifier());
- if (!ToQualifierOrErr)
- return ToQualifierOrErr.takeError();
- IdentifierInfo *Name = Importer.Import(T->getIdentifier());
- QualType Canon;
- if (T != T->getCanonicalTypeInternal().getTypePtr()) {
- if (ExpectedType TyOrErr = import(T->getCanonicalTypeInternal()))
- Canon = (*TyOrErr).getCanonicalType();
- else
- return TyOrErr.takeError();
- }
- return Importer.getToContext().getDependentNameType(T->getKeyword(),
- *ToQualifierOrErr,
- Name, Canon);
- }
- ExpectedType
- ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- Expected<ObjCInterfaceDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
- return Importer.getToContext().getObjCInterfaceType(*ToDeclOrErr);
- }
- ExpectedType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
- ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
- if (!ToBaseTypeOrErr)
- return ToBaseTypeOrErr.takeError();
- SmallVector<QualType, 4> TypeArgs;
- for (auto TypeArg : T->getTypeArgsAsWritten()) {
- if (ExpectedType TyOrErr = import(TypeArg))
- TypeArgs.push_back(*TyOrErr);
- else
- return TyOrErr.takeError();
- }
- SmallVector<ObjCProtocolDecl *, 4> Protocols;
- for (auto *P : T->quals()) {
- if (Expected<ObjCProtocolDecl *> ProtocolOrErr = import(P))
- Protocols.push_back(*ProtocolOrErr);
- else
- return ProtocolOrErr.takeError();
- }
- return Importer.getToContext().getObjCObjectType(*ToBaseTypeOrErr, TypeArgs,
- Protocols,
- T->isKindOfTypeAsWritten());
- }
- ExpectedType
- ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
- if (!ToPointeeTypeOrErr)
- return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getObjCObjectPointerType(*ToPointeeTypeOrErr);
- }
- //----------------------------------------------------------------------------
- // Import Declarations
- //----------------------------------------------------------------------------
- Error ASTNodeImporter::ImportDeclParts(
- NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
- DeclarationName &Name, NamedDecl *&ToD, SourceLocation &Loc) {
- // Check if RecordDecl is in FunctionDecl parameters to avoid infinite loop.
- // example: int struct_in_proto(struct data_t{int a;int b;} *d);
- DeclContext *OrigDC = D->getDeclContext();
- FunctionDecl *FunDecl;
- if (isa<RecordDecl>(D) && (FunDecl = dyn_cast<FunctionDecl>(OrigDC)) &&
- FunDecl->hasBody()) {
- auto getLeafPointeeType = [](const Type *T) {
- while (T->isPointerType() || T->isArrayType()) {
- T = T->getPointeeOrArrayElementType();
- }
- return T;
- };
- for (const ParmVarDecl *P : FunDecl->parameters()) {
- const Type *LeafT =
- getLeafPointeeType(P->getType().getCanonicalType().getTypePtr());
- auto *RT = dyn_cast<RecordType>(LeafT);
- if (RT && RT->getDecl() == D) {
- Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
- << D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- }
- }
- // Import the context of this declaration.
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return Err;
- // Import the name of this declaration.
- if (Error Err = importInto(Name, D->getDeclName()))
- return Err;
- // Import the location of this declaration.
- if (Error Err = importInto(Loc, D->getLocation()))
- return Err;
- ToD = cast_or_null<NamedDecl>(Importer.GetAlreadyImportedOrNull(D));
- if (ToD)
- if (Error Err = ASTNodeImporter(*this).ImportDefinitionIfNeeded(D, ToD))
- return Err;
- return Error::success();
- }
- Error ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
- if (!FromD)
- return Error::success();
- if (!ToD)
- if (Error Err = importInto(ToD, FromD))
- return Err;
- if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
- if (RecordDecl *ToRecord = cast<RecordDecl>(ToD)) {
- if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() &&
- !ToRecord->getDefinition()) {
- if (Error Err = ImportDefinition(FromRecord, ToRecord))
- return Err;
- }
- }
- return Error::success();
- }
- if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
- if (EnumDecl *ToEnum = cast<EnumDecl>(ToD)) {
- if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
- if (Error Err = ImportDefinition(FromEnum, ToEnum))
- return Err;
- }
- }
- return Error::success();
- }
- return Error::success();
- }
- Error
- ASTNodeImporter::ImportDeclarationNameLoc(
- const DeclarationNameInfo &From, DeclarationNameInfo& To) {
- // NOTE: To.Name and To.Loc are already imported.
- // We only have to import To.LocInfo.
- switch (To.getName().getNameKind()) {
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXUsingDirective:
- case DeclarationName::CXXDeductionGuideName:
- return Error::success();
- case DeclarationName::CXXOperatorName: {
- if (auto ToRangeOrErr = import(From.getCXXOperatorNameRange()))
- To.setCXXOperatorNameRange(*ToRangeOrErr);
- else
- return ToRangeOrErr.takeError();
- return Error::success();
- }
- case DeclarationName::CXXLiteralOperatorName: {
- if (ExpectedSLoc LocOrErr = import(From.getCXXLiteralOperatorNameLoc()))
- To.setCXXLiteralOperatorNameLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- return Error::success();
- }
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName: {
- if (auto ToTInfoOrErr = import(From.getNamedTypeInfo()))
- To.setNamedTypeInfo(*ToTInfoOrErr);
- else
- return ToTInfoOrErr.takeError();
- return Error::success();
- }
- }
- llvm_unreachable("Unknown name kind.");
- }
- Error
- ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
- if (Importer.isMinimalImport() && !ForceImport) {
- auto ToDCOrErr = Importer.ImportContext(FromDC);
- return ToDCOrErr.takeError();
- }
- llvm::SmallVector<Decl *, 8> ImportedDecls;
- for (auto *From : FromDC->decls()) {
- ExpectedDecl ImportedOrErr = import(From);
- if (!ImportedOrErr)
- // Ignore the error, continue with next Decl.
- // FIXME: Handle this case somehow better.
- consumeError(ImportedOrErr.takeError());
- }
- return Error::success();
- }
- Error ASTNodeImporter::ImportDeclContext(
- Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
- auto ToDCOrErr = Importer.ImportContext(FromD->getDeclContext());
- if (!ToDCOrErr)
- return ToDCOrErr.takeError();
- ToDC = *ToDCOrErr;
- if (FromD->getDeclContext() != FromD->getLexicalDeclContext()) {
- auto ToLexicalDCOrErr = Importer.ImportContext(
- FromD->getLexicalDeclContext());
- if (!ToLexicalDCOrErr)
- return ToLexicalDCOrErr.takeError();
- ToLexicalDC = *ToLexicalDCOrErr;
- } else
- ToLexicalDC = ToDC;
- return Error::success();
- }
- Error ASTNodeImporter::ImportImplicitMethods(
- const CXXRecordDecl *From, CXXRecordDecl *To) {
- assert(From->isCompleteDefinition() && To->getDefinition() == To &&
- "Import implicit methods to or from non-definition");
- for (CXXMethodDecl *FromM : From->methods())
- if (FromM->isImplicit()) {
- Expected<CXXMethodDecl *> ToMOrErr = import(FromM);
- if (!ToMOrErr)
- return ToMOrErr.takeError();
- }
- return Error::success();
- }
- static Error setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
- ASTImporter &Importer) {
- if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
- if (ExpectedDecl ToTypedefOrErr = Importer.Import(FromTypedef))
- To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
- else
- return ToTypedefOrErr.takeError();
- }
- return Error::success();
- }
- Error ASTNodeImporter::ImportDefinition(
- RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
- if (To->getDefinition() || To->isBeingDefined()) {
- if (Kind == IDK_Everything)
- return ImportDeclContext(From, /*ForceImport=*/true);
- return Error::success();
- }
- To->startDefinition();
- if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
- return Err;
- // Add base classes.
- auto *ToCXX = dyn_cast<CXXRecordDecl>(To);
- auto *FromCXX = dyn_cast<CXXRecordDecl>(From);
- if (ToCXX && FromCXX && ToCXX->dataPtr() && FromCXX->dataPtr()) {
- struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
- struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
- ToData.UserDeclaredConstructor = FromData.UserDeclaredConstructor;
- ToData.UserDeclaredSpecialMembers = FromData.UserDeclaredSpecialMembers;
- ToData.Aggregate = FromData.Aggregate;
- ToData.PlainOldData = FromData.PlainOldData;
- ToData.Empty = FromData.Empty;
- ToData.Polymorphic = FromData.Polymorphic;
- ToData.Abstract = FromData.Abstract;
- ToData.IsStandardLayout = FromData.IsStandardLayout;
- ToData.IsCXX11StandardLayout = FromData.IsCXX11StandardLayout;
- ToData.HasBasesWithFields = FromData.HasBasesWithFields;
- ToData.HasBasesWithNonStaticDataMembers =
- FromData.HasBasesWithNonStaticDataMembers;
- ToData.HasPrivateFields = FromData.HasPrivateFields;
- ToData.HasProtectedFields = FromData.HasProtectedFields;
- ToData.HasPublicFields = FromData.HasPublicFields;
- ToData.HasMutableFields = FromData.HasMutableFields;
- ToData.HasVariantMembers = FromData.HasVariantMembers;
- ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
- ToData.HasInClassInitializer = FromData.HasInClassInitializer;
- ToData.HasUninitializedReferenceMember
- = FromData.HasUninitializedReferenceMember;
- ToData.HasUninitializedFields = FromData.HasUninitializedFields;
- ToData.HasInheritedConstructor = FromData.HasInheritedConstructor;
- ToData.HasInheritedAssignment = FromData.HasInheritedAssignment;
- ToData.NeedOverloadResolutionForCopyConstructor
- = FromData.NeedOverloadResolutionForCopyConstructor;
- ToData.NeedOverloadResolutionForMoveConstructor
- = FromData.NeedOverloadResolutionForMoveConstructor;
- ToData.NeedOverloadResolutionForMoveAssignment
- = FromData.NeedOverloadResolutionForMoveAssignment;
- ToData.NeedOverloadResolutionForDestructor
- = FromData.NeedOverloadResolutionForDestructor;
- ToData.DefaultedCopyConstructorIsDeleted
- = FromData.DefaultedCopyConstructorIsDeleted;
- ToData.DefaultedMoveConstructorIsDeleted
- = FromData.DefaultedMoveConstructorIsDeleted;
- ToData.DefaultedMoveAssignmentIsDeleted
- = FromData.DefaultedMoveAssignmentIsDeleted;
- ToData.DefaultedDestructorIsDeleted = FromData.DefaultedDestructorIsDeleted;
- ToData.HasTrivialSpecialMembers = FromData.HasTrivialSpecialMembers;
- ToData.HasIrrelevantDestructor = FromData.HasIrrelevantDestructor;
- ToData.HasConstexprNonCopyMoveConstructor
- = FromData.HasConstexprNonCopyMoveConstructor;
- ToData.HasDefaultedDefaultConstructor
- = FromData.HasDefaultedDefaultConstructor;
- ToData.DefaultedDefaultConstructorIsConstexpr
- = FromData.DefaultedDefaultConstructorIsConstexpr;
- ToData.HasConstexprDefaultConstructor
- = FromData.HasConstexprDefaultConstructor;
- ToData.HasNonLiteralTypeFieldsOrBases
- = FromData.HasNonLiteralTypeFieldsOrBases;
- // ComputedVisibleConversions not imported.
- ToData.UserProvidedDefaultConstructor
- = FromData.UserProvidedDefaultConstructor;
- ToData.DeclaredSpecialMembers = FromData.DeclaredSpecialMembers;
- ToData.ImplicitCopyConstructorCanHaveConstParamForVBase
- = FromData.ImplicitCopyConstructorCanHaveConstParamForVBase;
- ToData.ImplicitCopyConstructorCanHaveConstParamForNonVBase
- = FromData.ImplicitCopyConstructorCanHaveConstParamForNonVBase;
- ToData.ImplicitCopyAssignmentHasConstParam
- = FromData.ImplicitCopyAssignmentHasConstParam;
- ToData.HasDeclaredCopyConstructorWithConstParam
- = FromData.HasDeclaredCopyConstructorWithConstParam;
- ToData.HasDeclaredCopyAssignmentWithConstParam
- = FromData.HasDeclaredCopyAssignmentWithConstParam;
- // Copy over the data stored in RecordDeclBits
- ToCXX->setArgPassingRestrictions(FromCXX->getArgPassingRestrictions());
- SmallVector<CXXBaseSpecifier *, 4> Bases;
- for (const auto &Base1 : FromCXX->bases()) {
- ExpectedType TyOrErr = import(Base1.getType());
- if (!TyOrErr)
- return TyOrErr.takeError();
- SourceLocation EllipsisLoc;
- if (Base1.isPackExpansion()) {
- if (ExpectedSLoc LocOrErr = import(Base1.getEllipsisLoc()))
- EllipsisLoc = *LocOrErr;
- else
- return LocOrErr.takeError();
- }
- // Ensure that we have a definition for the base.
- if (Error Err =
- ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl()))
- return Err;
- auto RangeOrErr = import(Base1.getSourceRange());
- if (!RangeOrErr)
- return RangeOrErr.takeError();
- auto TSIOrErr = import(Base1.getTypeSourceInfo());
- if (!TSIOrErr)
- return TSIOrErr.takeError();
- Bases.push_back(
- new (Importer.getToContext()) CXXBaseSpecifier(
- *RangeOrErr,
- Base1.isVirtual(),
- Base1.isBaseOfClass(),
- Base1.getAccessSpecifierAsWritten(),
- *TSIOrErr,
- EllipsisLoc));
- }
- if (!Bases.empty())
- ToCXX->setBases(Bases.data(), Bases.size());
- }
- if (shouldForceImportDeclContext(Kind))
- if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
- return Err;
- To->completeDefinition();
- return Error::success();
- }
- Error ASTNodeImporter::ImportInitializer(VarDecl *From, VarDecl *To) {
- if (To->getAnyInitializer())
- return Error::success();
- Expr *FromInit = From->getInit();
- if (!FromInit)
- return Error::success();
- ExpectedExpr ToInitOrErr = import(FromInit);
- if (!ToInitOrErr)
- return ToInitOrErr.takeError();
- To->setInit(*ToInitOrErr);
- if (From->isInitKnownICE()) {
- EvaluatedStmt *Eval = To->ensureEvaluatedStmt();
- Eval->CheckedICE = true;
- Eval->IsICE = From->isInitICE();
- }
- // FIXME: Other bits to merge?
- return Error::success();
- }
- Error ASTNodeImporter::ImportDefinition(
- EnumDecl *From, EnumDecl *To, ImportDefinitionKind Kind) {
- if (To->getDefinition() || To->isBeingDefined()) {
- if (Kind == IDK_Everything)
- return ImportDeclContext(From, /*ForceImport=*/true);
- return Error::success();
- }
- To->startDefinition();
- if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
- return Err;
- ExpectedType ToTypeOrErr =
- import(Importer.getFromContext().getTypeDeclType(From));
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedType ToPromotionTypeOrErr = import(From->getPromotionType());
- if (!ToPromotionTypeOrErr)
- return ToPromotionTypeOrErr.takeError();
- if (shouldForceImportDeclContext(Kind))
- if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
- return Err;
- // FIXME: we might need to merge the number of positive or negative bits
- // if the enumerator lists don't match.
- To->completeDefinition(*ToTypeOrErr, *ToPromotionTypeOrErr,
- From->getNumPositiveBits(),
- From->getNumNegativeBits());
- return Error::success();
- }
- Error ASTNodeImporter::ImportTemplateArguments(
- const TemplateArgument *FromArgs, unsigned NumFromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs) {
- for (unsigned I = 0; I != NumFromArgs; ++I) {
- if (auto ToOrErr = import(FromArgs[I]))
- ToArgs.push_back(*ToOrErr);
- else
- return ToOrErr.takeError();
- }
- return Error::success();
- }
- // FIXME: Do not forget to remove this and use only 'import'.
- Expected<TemplateArgument>
- ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
- return import(From);
- }
- template <typename InContainerTy>
- Error ASTNodeImporter::ImportTemplateArgumentListInfo(
- const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
- for (const auto &FromLoc : Container) {
- if (auto ToLocOrErr = import(FromLoc))
- ToTAInfo.addArgument(*ToLocOrErr);
- else
- return ToLocOrErr.takeError();
- }
- return Error::success();
- }
- static StructuralEquivalenceKind
- getStructuralEquivalenceKind(const ASTImporter &Importer) {
- return Importer.isMinimalImport() ? StructuralEquivalenceKind::Minimal
- : StructuralEquivalenceKind::Default;
- }
- bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
- false, Complain);
- return Ctx.IsEquivalent(From, To);
- }
- bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
- RecordDecl *ToRecord, bool Complain) {
- // Eliminate a potential failure point where we attempt to re-import
- // something we're trying to import while completing ToRecord.
- Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord);
- if (ToOrigin) {
- auto *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin);
- if (ToOriginRecord)
- ToRecord = ToOriginRecord;
- }
- StructuralEquivalenceContext Ctx(Importer.getFromContext(),
- ToRecord->getASTContext(),
- Importer.getNonEquivalentDecls(),
- getStructuralEquivalenceKind(Importer),
- false, Complain);
- return Ctx.IsEquivalent(FromRecord, ToRecord);
- }
- bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
- bool Complain) {
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
- false, Complain);
- return Ctx.IsEquivalent(FromVar, ToVar);
- }
- bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
- // Eliminate a potential failure point where we attempt to re-import
- // something we're trying to import while completing ToEnum.
- if (Decl *ToOrigin = Importer.GetOriginalDecl(ToEnum))
- if (auto *ToOriginEnum = dyn_cast<EnumDecl>(ToOrigin))
- ToEnum = ToOriginEnum;
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer));
- return Ctx.IsEquivalent(FromEnum, ToEnum);
- }
- bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From,
- FunctionTemplateDecl *To) {
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
- false, false);
- return Ctx.IsEquivalent(From, To);
- }
- bool ASTNodeImporter::IsStructuralMatch(FunctionDecl *From, FunctionDecl *To) {
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
- false, false);
- return Ctx.IsEquivalent(From, To);
- }
- bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
- EnumConstantDecl *ToEC) {
- const llvm::APSInt &FromVal = FromEC->getInitVal();
- const llvm::APSInt &ToVal = ToEC->getInitVal();
- return FromVal.isSigned() == ToVal.isSigned() &&
- FromVal.getBitWidth() == ToVal.getBitWidth() &&
- FromVal == ToVal;
- }
- bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
- ClassTemplateDecl *To) {
- StructuralEquivalenceContext Ctx(Importer.getFromContext(),
- Importer.getToContext(),
- Importer.getNonEquivalentDecls(),
- getStructuralEquivalenceKind(Importer));
- return Ctx.IsEquivalent(From, To);
- }
- bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
- VarTemplateDecl *To) {
- StructuralEquivalenceContext Ctx(Importer.getFromContext(),
- Importer.getToContext(),
- Importer.getNonEquivalentDecls(),
- getStructuralEquivalenceKind(Importer));
- return Ctx.IsEquivalent(From, To);
- }
- ExpectedDecl ASTNodeImporter::VisitDecl(Decl *D) {
- Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
- << D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedDecl ASTNodeImporter::VisitImportDecl(ImportDecl *D) {
- Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
- << D->getDeclKindName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedDecl ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
- // Import the context of this declaration.
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- // Import the location of this declaration.
- ExpectedSLoc LocOrErr = import(D->getLocation());
- if (!LocOrErr)
- return LocOrErr.takeError();
- EmptyDecl *ToD;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, *LocOrErr))
- return ToD;
- ToD->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToD);
- return ToD;
- }
- ExpectedDecl ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
- TranslationUnitDecl *ToD =
- Importer.getToContext().getTranslationUnitDecl();
- Importer.MapImported(D, ToD);
- return ToD;
- }
- ExpectedDecl ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
- ExpectedSLoc LocOrErr = import(D->getLocation());
- if (!LocOrErr)
- return LocOrErr.takeError();
- auto ColonLocOrErr = import(D->getColonLoc());
- if (!ColonLocOrErr)
- return ColonLocOrErr.takeError();
- // Import the context of this declaration.
- auto DCOrErr = Importer.ImportContext(D->getDeclContext());
- if (!DCOrErr)
- return DCOrErr.takeError();
- DeclContext *DC = *DCOrErr;
- AccessSpecDecl *ToD;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), D->getAccess(),
- DC, *LocOrErr, *ColonLocOrErr))
- return ToD;
- // Lexical DeclContext and Semantic DeclContext
- // is always the same for the accessSpec.
- ToD->setLexicalDeclContext(DC);
- DC->addDeclInternal(ToD);
- return ToD;
- }
- ExpectedDecl ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
- auto DCOrErr = Importer.ImportContext(D->getDeclContext());
- if (!DCOrErr)
- return DCOrErr.takeError();
- DeclContext *DC = *DCOrErr;
- DeclContext *LexicalDC = DC;
- SourceLocation ToLocation, ToRParenLoc;
- Expr *ToAssertExpr;
- StringLiteral *ToMessage;
- if (auto Imp = importSeq(
- D->getLocation(), D->getAssertExpr(), D->getMessage(), D->getRParenLoc()))
- std::tie(ToLocation, ToAssertExpr, ToMessage, ToRParenLoc) = *Imp;
- else
- return Imp.takeError();
- StaticAssertDecl *ToD;
- if (GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(), DC, ToLocation, ToAssertExpr, ToMessage,
- ToRParenLoc, D->isFailed()))
- return ToD;
- ToD->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToD);
- return ToD;
- }
- ExpectedDecl ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
- // Import the major distinguishing characteristics of this namespace.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- NamespaceDecl *MergeWithNamespace = nullptr;
- if (!Name) {
- // This is an anonymous namespace. Adopt an existing anonymous
- // namespace if we can.
- // FIXME: Not testable.
- if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
- MergeWithNamespace = TU->getAnonymousNamespace();
- else
- MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
- } else {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Namespace))
- continue;
- if (auto *FoundNS = dyn_cast<NamespaceDecl>(FoundDecl)) {
- MergeWithNamespace = FoundNS;
- ConflictingDecls.clear();
- break;
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- // Create the "to" namespace, if needed.
- NamespaceDecl *ToNamespace = MergeWithNamespace;
- if (!ToNamespace) {
- if (GetImportedOrCreateDecl(
- ToNamespace, D, Importer.getToContext(), DC, D->isInline(),
- *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
- /*PrevDecl=*/nullptr))
- return ToNamespace;
- ToNamespace->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToNamespace);
- // If this is an anonymous namespace, register it as the anonymous
- // namespace within its context.
- if (!Name) {
- if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
- TU->setAnonymousNamespace(ToNamespace);
- else
- cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
- }
- }
- Importer.MapImported(D, ToNamespace);
- if (Error Err = ImportDeclContext(D))
- return std::move(Err);
- return ToNamespace;
- }
- ExpectedDecl ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
- // Import the major distinguishing characteristics of this namespace.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *LookupD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
- return std::move(Err);
- if (LookupD)
- return LookupD;
- // NOTE: No conflict resolution is done for namespace aliases now.
- SourceLocation ToNamespaceLoc, ToAliasLoc, ToTargetNameLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- NamespaceDecl *ToNamespace;
- if (auto Imp = importSeq(
- D->getNamespaceLoc(), D->getAliasLoc(), D->getQualifierLoc(),
- D->getTargetNameLoc(), D->getNamespace()))
- std::tie(
- ToNamespaceLoc, ToAliasLoc, ToQualifierLoc, ToTargetNameLoc,
- ToNamespace) = *Imp;
- else
- return Imp.takeError();
- IdentifierInfo *ToIdentifier = Importer.Import(D->getIdentifier());
- NamespaceAliasDecl *ToD;
- if (GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(), DC, ToNamespaceLoc, ToAliasLoc,
- ToIdentifier, ToQualifierLoc, ToTargetNameLoc, ToNamespace))
- return ToD;
- ToD->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToD);
- return ToD;
- }
- ExpectedDecl
- ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
- // Import the major distinguishing characteristics of this typedef.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // If this typedef is not in block scope, determine whether we've
- // seen a typedef with the same name (that we can merge with) or any
- // other entity by that name (which name lookup could conflict with).
- if (!DC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundTypedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
- QualType FromUT = D->getUnderlyingType();
- QualType FoundUT = FoundTypedef->getUnderlyingType();
- if (Importer.IsStructurallyEquivalent(FromUT, FoundUT)) {
- // If the "From" context has a complete underlying type but we
- // already have a complete underlying type then return with that.
- if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType())
- return Importer.MapImported(D, FoundTypedef);
- }
- // FIXME Handle redecl chain. When you do that make consistent changes
- // in ASTImporterLookupTable too.
- break;
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- QualType ToUnderlyingType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceLocation ToBeginLoc;
- if (auto Imp = importSeq(
- D->getUnderlyingType(), D->getTypeSourceInfo(), D->getBeginLoc()))
- std::tie(ToUnderlyingType, ToTypeSourceInfo, ToBeginLoc) = *Imp;
- else
- return Imp.takeError();
- // Create the new typedef node.
- // FIXME: ToUnderlyingType is not used.
- TypedefNameDecl *ToTypedef;
- if (IsAlias) {
- if (GetImportedOrCreateDecl<TypeAliasDecl>(
- ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
- Name.getAsIdentifierInfo(), ToTypeSourceInfo))
- return ToTypedef;
- } else if (GetImportedOrCreateDecl<TypedefDecl>(
- ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
- Name.getAsIdentifierInfo(), ToTypeSourceInfo))
- return ToTypedef;
- ToTypedef->setAccess(D->getAccess());
- ToTypedef->setLexicalDeclContext(LexicalDC);
- // Templated declarations should not appear in DeclContext.
- TypeAliasDecl *FromAlias = IsAlias ? cast<TypeAliasDecl>(D) : nullptr;
- if (!FromAlias || !FromAlias->getDescribedAliasTemplate())
- LexicalDC->addDeclInternal(ToTypedef);
- return ToTypedef;
- }
- ExpectedDecl ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
- return VisitTypedefNameDecl(D, /*IsAlias=*/false);
- }
- ExpectedDecl ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
- return VisitTypedefNameDecl(D, /*IsAlias=*/true);
- }
- ExpectedDecl
- ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
- // Import the major distinguishing characteristics of this typedef.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *FoundD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
- return std::move(Err);
- if (FoundD)
- return FoundD;
- // If this typedef is not in block scope, determine whether we've
- // seen a typedef with the same name (that we can merge with) or any
- // other entity by that name (which name lookup could conflict with).
- if (!DC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl))
- return Importer.MapImported(D, FoundAlias);
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- TemplateParameterList *ToTemplateParameters;
- TypeAliasDecl *ToTemplatedDecl;
- if (auto Imp = importSeq(D->getTemplateParameters(), D->getTemplatedDecl()))
- std::tie(ToTemplateParameters, ToTemplatedDecl) = *Imp;
- else
- return Imp.takeError();
- TypeAliasTemplateDecl *ToAlias;
- if (GetImportedOrCreateDecl(ToAlias, D, Importer.getToContext(), DC, Loc,
- Name, ToTemplateParameters, ToTemplatedDecl))
- return ToAlias;
- ToTemplatedDecl->setDescribedAliasTemplate(ToAlias);
- ToAlias->setAccess(D->getAccess());
- ToAlias->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToAlias);
- return ToAlias;
- }
- ExpectedDecl ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
- // Import the major distinguishing characteristics of this label.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- assert(LexicalDC->isFunctionOrMethod());
- LabelDecl *ToLabel;
- if (D->isGnuLocal()) {
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(), *BeginLocOrErr))
- return ToLabel;
- } else {
- if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo()))
- return ToLabel;
- }
- Expected<LabelStmt *> ToStmtOrErr = import(D->getStmt());
- if (!ToStmtOrErr)
- return ToStmtOrErr.takeError();
- ToLabel->setStmt(*ToStmtOrErr);
- ToLabel->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToLabel);
- return ToLabel;
- }
- ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
- // Import the major distinguishing characteristics of this enum.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Figure out what enum name we're looking for.
- unsigned IDNS = Decl::IDNS_Tag;
- DeclarationName SearchName = Name;
- if (!SearchName && D->getTypedefNameForAnonDecl()) {
- if (Error Err = importInto(
- SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
- return std::move(Err);
- IDNS = Decl::IDNS_Ordinary;
- } else if (Importer.getToContext().getLangOpts().CPlusPlus)
- IDNS |= Decl::IDNS_Ordinary;
- // We may already have an enum of the same name; try to find and match it.
- if (!DC->isFunctionOrMethod() && SearchName) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- auto FoundDecls =
- Importer.findDeclsInToCtx(DC, SearchName);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
- if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- FoundDecl = Tag->getDecl();
- }
- if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
- if (IsStructuralMatch(D, FoundEnum))
- return Importer.MapImported(D, FoundEnum);
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- SourceLocation ToBeginLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- QualType ToIntegerType;
- if (auto Imp = importSeq(
- D->getBeginLoc(), D->getQualifierLoc(), D->getIntegerType()))
- std::tie(ToBeginLoc, ToQualifierLoc, ToIntegerType) = *Imp;
- else
- return Imp.takeError();
- // Create the enum declaration.
- EnumDecl *D2;
- if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), DC, ToBeginLoc,
- Loc, Name.getAsIdentifierInfo(), nullptr, D->isScoped(),
- D->isScopedUsingClassTag(), D->isFixed()))
- return D2;
- D2->setQualifierInfo(ToQualifierLoc);
- D2->setIntegerType(ToIntegerType);
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
- // Import the definition
- if (D->isCompleteDefinition())
- if (Error Err = ImportDefinition(D, D2))
- return std::move(Err);
- return D2;
- }
- ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
- bool IsFriendTemplate = false;
- if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
- IsFriendTemplate =
- DCXX->getDescribedClassTemplate() &&
- DCXX->getDescribedClassTemplate()->getFriendObjectKind() !=
- Decl::FOK_None;
- }
- // Import the major distinguishing characteristics of this record.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Figure out what structure name we're looking for.
- unsigned IDNS = Decl::IDNS_Tag;
- DeclarationName SearchName = Name;
- if (!SearchName && D->getTypedefNameForAnonDecl()) {
- if (Error Err = importInto(
- SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
- return std::move(Err);
- IDNS = Decl::IDNS_Ordinary;
- } else if (Importer.getToContext().getLangOpts().CPlusPlus)
- IDNS |= Decl::IDNS_Ordinary | Decl::IDNS_TagFriend;
- // We may already have a record of the same name; try to find and match it.
- RecordDecl *PrevDecl = nullptr;
- if (!DC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- auto FoundDecls =
- Importer.findDeclsInToCtx(DC, SearchName);
- if (!FoundDecls.empty()) {
- // We're going to have to compare D against potentially conflicting Decls,
- // so complete it.
- if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
- D->getASTContext().getExternalSource()->CompleteType(D);
- }
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- Decl *Found = FoundDecl;
- if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
- if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- Found = Tag->getDecl();
- }
- if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
- // Do not emit false positive diagnostic in case of unnamed
- // struct/union and in case of anonymous structs. Would be false
- // because there may be several anonymous/unnamed structs in a class.
- // E.g. these are both valid:
- // struct A { // unnamed structs
- // struct { struct A *next; } entry0;
- // struct { struct A *next; } entry1;
- // };
- // struct X { struct { int a; }; struct { int b; }; }; // anon structs
- if (!SearchName)
- if (!IsStructuralMatch(D, FoundRecord, false))
- continue;
- if (!hasSameVisibilityContext(FoundRecord, D))
- continue;
- if (IsStructuralMatch(D, FoundRecord)) {
- RecordDecl *FoundDef = FoundRecord->getDefinition();
- if (D->isThisDeclarationADefinition() && FoundDef) {
- // FIXME: Structural equivalence check should check for same
- // user-defined methods.
- Importer.MapImported(D, FoundDef);
- if (const auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
- auto *FoundCXX = dyn_cast<CXXRecordDecl>(FoundDef);
- assert(FoundCXX && "Record type mismatch");
- if (!Importer.isMinimalImport())
- // FoundDef may not have every implicit method that D has
- // because implicit methods are created only if they are used.
- if (Error Err = ImportImplicitMethods(DCXX, FoundCXX))
- return std::move(Err);
- }
- }
- PrevDecl = FoundRecord->getMostRecentDecl();
- break;
- }
- }
- ConflictingDecls.push_back(FoundDecl);
- } // for
- if (!ConflictingDecls.empty() && SearchName) {
- Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- // Create the record declaration.
- RecordDecl *D2 = nullptr;
- CXXRecordDecl *D2CXX = nullptr;
- if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
- if (DCXX->isLambda()) {
- auto TInfoOrErr = import(DCXX->getLambdaTypeInfo());
- if (!TInfoOrErr)
- return TInfoOrErr.takeError();
- if (GetImportedOrCreateSpecialDecl(
- D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
- DC, *TInfoOrErr, Loc, DCXX->isDependentLambda(),
- DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
- return D2CXX;
- ExpectedDecl CDeclOrErr = import(DCXX->getLambdaContextDecl());
- if (!CDeclOrErr)
- return CDeclOrErr.takeError();
- D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr);
- } else if (DCXX->isInjectedClassName()) {
- // We have to be careful to do a similar dance to the one in
- // Sema::ActOnStartCXXMemberDeclarations
- const bool DelayTypeCreation = true;
- if (GetImportedOrCreateDecl(
- D2CXX, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
- cast_or_null<CXXRecordDecl>(PrevDecl), DelayTypeCreation))
- return D2CXX;
- Importer.getToContext().getTypeDeclType(
- D2CXX, dyn_cast<CXXRecordDecl>(DC));
- } else {
- if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
- D->getTagKind(), DC, *BeginLocOrErr, Loc,
- Name.getAsIdentifierInfo(),
- cast_or_null<CXXRecordDecl>(PrevDecl)))
- return D2CXX;
- }
- D2 = D2CXX;
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
- LexicalDC->addDeclInternal(D2);
- if (LexicalDC != DC && D->isInIdentifierNamespace(Decl::IDNS_TagFriend))
- DC->makeDeclVisibleInContext(D2);
- if (ClassTemplateDecl *FromDescribed =
- DCXX->getDescribedClassTemplate()) {
- ClassTemplateDecl *ToDescribed;
- if (Error Err = importInto(ToDescribed, FromDescribed))
- return std::move(Err);
- D2CXX->setDescribedClassTemplate(ToDescribed);
- if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
- // In a record describing a template the type should be an
- // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
- // previously set type to the correct value here (ToDescribed is not
- // available at record create).
- // FIXME: The previous type is cleared but not removed from
- // ASTContext's internal storage.
- CXXRecordDecl *Injected = nullptr;
- for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
- auto *Record = dyn_cast<CXXRecordDecl>(Found);
- if (Record && Record->isInjectedClassName()) {
- Injected = Record;
- break;
- }
- }
- // Create an injected type for the whole redecl chain.
- SmallVector<Decl *, 2> Redecls =
- getCanonicalForwardRedeclChain(D2CXX);
- for (auto *R : Redecls) {
- auto *RI = cast<CXXRecordDecl>(R);
- RI->setTypeForDecl(nullptr);
- // Below we create a new injected type and assign that to the
- // canonical decl, subsequent declarations in the chain will reuse
- // that type.
- Importer.getToContext().getInjectedClassNameType(
- RI, ToDescribed->getInjectedClassNameSpecialization());
- }
- // Set the new type for the previous injected decl too.
- if (Injected) {
- Injected->setTypeForDecl(nullptr);
- Importer.getToContext().getTypeDeclType(Injected, D2CXX);
- }
- }
- } else if (MemberSpecializationInfo *MemberInfo =
- DCXX->getMemberSpecializationInfo()) {
- TemplateSpecializationKind SK =
- MemberInfo->getTemplateSpecializationKind();
- CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass();
- if (Expected<CXXRecordDecl *> ToInstOrErr = import(FromInst))
- D2CXX->setInstantiationOfMemberClass(*ToInstOrErr, SK);
- else
- return ToInstOrErr.takeError();
- if (ExpectedSLoc POIOrErr =
- import(MemberInfo->getPointOfInstantiation()))
- D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
- *POIOrErr);
- else
- return POIOrErr.takeError();
- }
- } else {
- if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
- D->getTagKind(), DC, *BeginLocOrErr, Loc,
- Name.getAsIdentifierInfo(), PrevDecl))
- return D2;
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
- }
- if (auto QualifierLocOrErr = import(D->getQualifierLoc()))
- D2->setQualifierInfo(*QualifierLocOrErr);
- else
- return QualifierLocOrErr.takeError();
- if (D->isAnonymousStructOrUnion())
- D2->setAnonymousStructOrUnion(true);
- if (D->isCompleteDefinition())
- if (Error Err = ImportDefinition(D, D2, IDK_Default))
- return std::move(Err);
- return D2;
- }
- ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
- // Import the major distinguishing characteristics of this enumerator.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Determine whether there are any other declarations with the same name and
- // in the same context.
- if (!LexicalDC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundEnumConstant = dyn_cast<EnumConstantDecl>(FoundDecl)) {
- if (IsStructuralMatch(D, FoundEnumConstant))
- return Importer.MapImported(D, FoundEnumConstant);
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- ExpectedType TypeOrErr = import(D->getType());
- if (!TypeOrErr)
- return TypeOrErr.takeError();
- ExpectedExpr InitOrErr = import(D->getInitExpr());
- if (!InitOrErr)
- return InitOrErr.takeError();
- EnumConstantDecl *ToEnumerator;
- if (GetImportedOrCreateDecl(
- ToEnumerator, D, Importer.getToContext(), cast<EnumDecl>(DC), Loc,
- Name.getAsIdentifierInfo(), *TypeOrErr, *InitOrErr, D->getInitVal()))
- return ToEnumerator;
- ToEnumerator->setAccess(D->getAccess());
- ToEnumerator->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToEnumerator);
- return ToEnumerator;
- }
- Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD,
- DeclaratorDecl *ToD) {
- unsigned int Num = FromD->getNumTemplateParameterLists();
- if (Num == 0)
- return Error::success();
- SmallVector<TemplateParameterList *, 2> ToTPLists(Num);
- for (unsigned int I = 0; I < Num; ++I)
- if (Expected<TemplateParameterList *> ToTPListOrErr =
- import(FromD->getTemplateParameterList(I)))
- ToTPLists[I] = *ToTPListOrErr;
- else
- return ToTPListOrErr.takeError();
- ToD->setTemplateParameterListsInfo(Importer.ToContext, ToTPLists);
- return Error::success();
- }
- Error ASTNodeImporter::ImportTemplateInformation(
- FunctionDecl *FromFD, FunctionDecl *ToFD) {
- switch (FromFD->getTemplatedKind()) {
- case FunctionDecl::TK_NonTemplate:
- case FunctionDecl::TK_FunctionTemplate:
- return Error::success();
- case FunctionDecl::TK_MemberSpecialization: {
- TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind();
- if (Expected<FunctionDecl *> InstFDOrErr =
- import(FromFD->getInstantiatedFromMemberFunction()))
- ToFD->setInstantiationOfMemberFunction(*InstFDOrErr, TSK);
- else
- return InstFDOrErr.takeError();
- if (ExpectedSLoc POIOrErr = import(
- FromFD->getMemberSpecializationInfo()->getPointOfInstantiation()))
- ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- return Error::success();
- }
- case FunctionDecl::TK_FunctionTemplateSpecialization: {
- auto FunctionAndArgsOrErr =
- ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
- if (!FunctionAndArgsOrErr)
- return FunctionAndArgsOrErr.takeError();
- TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
- Importer.getToContext(), std::get<1>(*FunctionAndArgsOrErr));
- auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
- TemplateArgumentListInfo ToTAInfo;
- const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
- if (FromTAArgsAsWritten)
- if (Error Err = ImportTemplateArgumentListInfo(
- *FromTAArgsAsWritten, ToTAInfo))
- return Err;
- ExpectedSLoc POIOrErr = import(FTSInfo->getPointOfInstantiation());
- if (!POIOrErr)
- return POIOrErr.takeError();
- if (Error Err = ImportTemplateParameterLists(FromFD, ToFD))
- return Err;
- TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
- ToFD->setFunctionTemplateSpecialization(
- std::get<0>(*FunctionAndArgsOrErr), ToTAList, /* InsertPos= */ nullptr,
- TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, *POIOrErr);
- return Error::success();
- }
- case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
- auto *FromInfo = FromFD->getDependentSpecializationInfo();
- UnresolvedSet<8> TemplDecls;
- unsigned NumTemplates = FromInfo->getNumTemplates();
- for (unsigned I = 0; I < NumTemplates; I++) {
- if (Expected<FunctionTemplateDecl *> ToFTDOrErr =
- import(FromInfo->getTemplate(I)))
- TemplDecls.addDecl(*ToFTDOrErr);
- else
- return ToFTDOrErr.takeError();
- }
- // Import TemplateArgumentListInfo.
- TemplateArgumentListInfo ToTAInfo;
- if (Error Err = ImportTemplateArgumentListInfo(
- FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
- llvm::makeArrayRef(
- FromInfo->getTemplateArgs(), FromInfo->getNumTemplateArgs()),
- ToTAInfo))
- return Err;
- ToFD->setDependentTemplateSpecialization(Importer.getToContext(),
- TemplDecls, ToTAInfo);
- return Error::success();
- }
- }
- llvm_unreachable("All cases should be covered!");
- }
- Expected<FunctionDecl *>
- ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
- auto FunctionAndArgsOrErr =
- ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
- if (!FunctionAndArgsOrErr)
- return FunctionAndArgsOrErr.takeError();
- FunctionTemplateDecl *Template;
- TemplateArgsTy ToTemplArgs;
- std::tie(Template, ToTemplArgs) = *FunctionAndArgsOrErr;
- void *InsertPos = nullptr;
- auto *FoundSpec = Template->findSpecialization(ToTemplArgs, InsertPos);
- return FoundSpec;
- }
- Error ASTNodeImporter::ImportFunctionDeclBody(FunctionDecl *FromFD,
- FunctionDecl *ToFD) {
- if (Stmt *FromBody = FromFD->getBody()) {
- if (ExpectedStmt ToBodyOrErr = import(FromBody))
- ToFD->setBody(*ToBodyOrErr);
- else
- return ToBodyOrErr.takeError();
- }
- return Error::success();
- }
- template <typename T>
- bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) {
- if (From->hasExternalFormalLinkage())
- return Found->hasExternalFormalLinkage();
- if (Importer.GetFromTU(Found) != From->getTranslationUnitDecl())
- return false;
- if (From->isInAnonymousNamespace())
- return Found->isInAnonymousNamespace();
- else
- return !Found->isInAnonymousNamespace() &&
- !Found->hasExternalFormalLinkage();
- }
- ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
- SmallVector<Decl *, 2> Redecls = getCanonicalForwardRedeclChain(D);
- auto RedeclIt = Redecls.begin();
- // Import the first part of the decl chain. I.e. import all previous
- // declarations starting from the canonical decl.
- for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt) {
- ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
- if (!ToRedeclOrErr)
- return ToRedeclOrErr.takeError();
- }
- assert(*RedeclIt == D);
- // Import the major distinguishing characteristics of this function.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- FunctionDecl *FoundByLookup = nullptr;
- FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
- // If this is a function template specialization, then try to find the same
- // existing specialization in the "to" context. The lookup below will not
- // find any specialization, but would find the primary template; thus, we
- // have to skip normal lookup in case of specializations.
- // FIXME handle member function templates (TK_MemberSpecialization) similarly?
- if (D->getTemplatedKind() ==
- FunctionDecl::TK_FunctionTemplateSpecialization) {
- auto FoundFunctionOrErr = FindFunctionTemplateSpecialization(D);
- if (!FoundFunctionOrErr)
- return FoundFunctionOrErr.takeError();
- if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
- if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
- return Def;
- FoundByLookup = FoundFunction;
- }
- }
- // Try to find a function in our own ("to") context with the same name, same
- // type, and in the same context as the function we're importing.
- else if (!LexicalDC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) {
- if (!hasSameVisibilityContext(FoundFunction, D))
- continue;
- if (IsStructuralMatch(D, FoundFunction)) {
- if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
- return Def;
- FoundByLookup = FoundFunction;
- break;
- }
- // FIXME: Check for overloading more carefully, e.g., by boosting
- // Sema::IsOverload out to the AST library.
- // Function overloading is okay in C++.
- if (Importer.getToContext().getLangOpts().CPlusPlus)
- continue;
- // Complain about inconsistent function types.
- Importer.ToDiag(Loc, diag::warn_odr_function_type_inconsistent)
- << Name << D->getType() << FoundFunction->getType();
- Importer.ToDiag(FoundFunction->getLocation(), diag::note_odr_value_here)
- << FoundFunction->getType();
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- // We do not allow more than one in-class declaration of a function. This is
- // because AST clients like VTableBuilder asserts on this. VTableBuilder
- // assumes there is only one in-class declaration. Building a redecl
- // chain would result in more than one in-class declaration for
- // overrides (even if they are part of the same redecl chain inside the
- // derived class.)
- if (FoundByLookup) {
- if (isa<CXXMethodDecl>(FoundByLookup)) {
- if (D->getLexicalDeclContext() == D->getDeclContext()) {
- if (!D->doesThisDeclarationHaveABody())
- return Importer.MapImported(D, FoundByLookup);
- else {
- // Let's continue and build up the redecl chain in this case.
- // FIXME Merge the functions into one decl.
- }
- }
- }
- }
- DeclarationNameInfo NameInfo(Name, Loc);
- // Import additional name location/type info.
- if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
- return std::move(Err);
- QualType FromTy = D->getType();
- bool usedDifferentExceptionSpec = false;
- if (const auto *FromFPT = D->getType()->getAs<FunctionProtoType>()) {
- FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
- // FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
- // FunctionDecl that we are importing the FunctionProtoType for.
- // To avoid an infinite recursion when importing, create the FunctionDecl
- // with a simplified function type and update it afterwards.
- if (FromEPI.ExceptionSpec.SourceDecl ||
- FromEPI.ExceptionSpec.SourceTemplate ||
- FromEPI.ExceptionSpec.NoexceptExpr) {
- FunctionProtoType::ExtProtoInfo DefaultEPI;
- FromTy = Importer.getFromContext().getFunctionType(
- FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI);
- usedDifferentExceptionSpec = true;
- }
- }
- QualType T;
- TypeSourceInfo *TInfo;
- SourceLocation ToInnerLocStart, ToEndLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- FromTy, D->getTypeSourceInfo(), D->getInnerLocStart(),
- D->getQualifierLoc(), D->getEndLoc()))
- std::tie(T, TInfo, ToInnerLocStart, ToQualifierLoc, ToEndLoc) = *Imp;
- else
- return Imp.takeError();
- // Import the function parameters.
- SmallVector<ParmVarDecl *, 8> Parameters;
- for (auto P : D->parameters()) {
- if (Expected<ParmVarDecl *> ToPOrErr = import(P))
- Parameters.push_back(*ToPOrErr);
- else
- return ToPOrErr.takeError();
- }
- // Create the imported function.
- FunctionDecl *ToFunction = nullptr;
- if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
- Expr *ExplicitExpr = nullptr;
- if (FromConstructor->getExplicitSpecifier().getExpr()) {
- auto Imp = importSeq(FromConstructor->getExplicitSpecifier().getExpr());
- if (!Imp)
- return Imp.takeError();
- std::tie(ExplicitExpr) = *Imp;
- }
- if (GetImportedOrCreateDecl<CXXConstructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo,
- ExplicitSpecifier(
- ExplicitExpr,
- FromConstructor->getExplicitSpecifier().getKind()),
- D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
- return ToFunction;
- } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
- auto Imp =
- importSeq(const_cast<FunctionDecl *>(FromDtor->getOperatorDelete()),
- FromDtor->getOperatorDeleteThisArg());
- if (!Imp)
- return Imp.takeError();
- FunctionDecl *ToOperatorDelete;
- Expr *ToThisArg;
- std::tie(ToOperatorDelete, ToThisArg) = *Imp;
- if (GetImportedOrCreateDecl<CXXDestructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
- D->isImplicit()))
- return ToFunction;
- CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
- ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg);
- } else if (CXXConversionDecl *FromConversion =
- dyn_cast<CXXConversionDecl>(D)) {
- Expr *ExplicitExpr = nullptr;
- if (FromConversion->getExplicitSpecifier().getExpr()) {
- auto Imp = importSeq(FromConversion->getExplicitSpecifier().getExpr());
- if (!Imp)
- return Imp.takeError();
- std::tie(ExplicitExpr) = *Imp;
- }
- if (GetImportedOrCreateDecl<CXXConversionDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
- ExplicitSpecifier(ExplicitExpr,
- FromConversion->getExplicitSpecifier().getKind()),
- D->isConstexpr(), SourceLocation()))
- return ToFunction;
- } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
- if (GetImportedOrCreateDecl<CXXMethodDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
- Method->isInlineSpecified(), D->isConstexpr(), SourceLocation()))
- return ToFunction;
- } else {
- if (GetImportedOrCreateDecl(ToFunction, D, Importer.getToContext(), DC,
- ToInnerLocStart, NameInfo, T, TInfo,
- D->getStorageClass(), D->isInlineSpecified(),
- D->hasWrittenPrototype(), D->isConstexpr()))
- return ToFunction;
- }
- // Connect the redecl chain.
- if (FoundByLookup) {
- auto *Recent = const_cast<FunctionDecl *>(
- FoundByLookup->getMostRecentDecl());
- ToFunction->setPreviousDecl(Recent);
- // FIXME Probably we should merge exception specifications. E.g. In the
- // "To" context the existing function may have exception specification with
- // noexcept-unevaluated, while the newly imported function may have an
- // evaluated noexcept. A call to adjustExceptionSpec() on the imported
- // decl and its redeclarations may be required.
- }
- // Import Ctor initializers.
- if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
- if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
- SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
- // Import first, then allocate memory and copy if there was no error.
- if (Error Err = ImportContainerChecked(
- FromConstructor->inits(), CtorInitializers))
- return std::move(Err);
- auto **Memory =
- new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
- std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
- auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
- ToCtor->setCtorInitializers(Memory);
- ToCtor->setNumCtorInitializers(NumInitializers);
- }
- }
- ToFunction->setQualifierInfo(ToQualifierLoc);
- ToFunction->setAccess(D->getAccess());
- ToFunction->setLexicalDeclContext(LexicalDC);
- ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
- ToFunction->setTrivial(D->isTrivial());
- ToFunction->setPure(D->isPure());
- ToFunction->setRangeEnd(ToEndLoc);
- // Set the parameters.
- for (auto *Param : Parameters) {
- Param->setOwningFunction(ToFunction);
- ToFunction->addDeclInternal(Param);
- }
- ToFunction->setParams(Parameters);
- // We need to complete creation of FunctionProtoTypeLoc manually with setting
- // params it refers to.
- if (TInfo) {
- if (auto ProtoLoc =
- TInfo->getTypeLoc().IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
- for (unsigned I = 0, N = Parameters.size(); I != N; ++I)
- ProtoLoc.setParam(I, Parameters[I]);
- }
- }
- if (usedDifferentExceptionSpec) {
- // Update FunctionProtoType::ExtProtoInfo.
- if (ExpectedType TyOrErr = import(D->getType()))
- ToFunction->setType(*TyOrErr);
- else
- return TyOrErr.takeError();
- }
- // Import the describing template function, if any.
- if (FromFT) {
- auto ToFTOrErr = import(FromFT);
- if (!ToFTOrErr)
- return ToFTOrErr.takeError();
- }
- if (D->doesThisDeclarationHaveABody()) {
- Error Err = ImportFunctionDeclBody(D, ToFunction);
- if (Err)
- return std::move(Err);
- }
- // FIXME: Other bits to merge?
- // If it is a template, import all related things.
- if (Error Err = ImportTemplateInformation(D, ToFunction))
- return std::move(Err);
- bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
- // TODO Can we generalize this approach to other AST nodes as well?
- if (D->getDeclContext()->containsDeclAndLoad(D))
- DC->addDeclInternal(ToFunction);
- if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
- LexicalDC->addDeclInternal(ToFunction);
- // Friend declaration's lexical context is the befriending class, but the
- // semantic context is the enclosing scope of the befriending class.
- // We want the friend functions to be found in the semantic context by lookup.
- // FIXME should we handle this generically in VisitFriendDecl?
- // In Other cases when LexicalDC != DC we don't want it to be added,
- // e.g out-of-class definitions like void B::f() {} .
- if (LexicalDC != DC && IsFriend) {
- DC->makeDeclVisibleInContext(ToFunction);
- }
- if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
- ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);
- // Import the rest of the chain. I.e. import all subsequent declarations.
- for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
- ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
- if (!ToRedeclOrErr)
- return ToRedeclOrErr.takeError();
- }
- return ToFunction;
- }
- ExpectedDecl ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
- return VisitFunctionDecl(D);
- }
- ExpectedDecl ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
- return VisitCXXMethodDecl(D);
- }
- ExpectedDecl ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
- return VisitCXXMethodDecl(D);
- }
- ExpectedDecl ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
- return VisitCXXMethodDecl(D);
- }
- ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
- // Import the major distinguishing characteristics of a variable.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Determine whether we've already imported this field.
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
- // For anonymous fields, match up by index.
- if (!Name &&
- ASTImporter::getFieldIndex(D) !=
- ASTImporter::getFieldIndex(FoundField))
- continue;
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundField->getType())) {
- Importer.MapImported(D, FoundField);
- // In case of a FieldDecl of a ClassTemplateSpecializationDecl, the
- // initializer of a FieldDecl might not had been instantiated in the
- // "To" context. However, the "From" context might instantiated that,
- // thus we have to merge that.
- if (Expr *FromInitializer = D->getInClassInitializer()) {
- // We don't have yet the initializer set.
- if (FoundField->hasInClassInitializer() &&
- !FoundField->getInClassInitializer()) {
- if (ExpectedExpr ToInitializerOrErr = import(FromInitializer))
- FoundField->setInClassInitializer(*ToInitializerOrErr);
- else {
- // We can't return error here,
- // since we already mapped D as imported.
- // FIXME: warning message?
- consumeError(ToInitializerOrErr.takeError());
- return FoundField;
- }
- }
- }
- return FoundField;
- }
- // FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
- << Name << D->getType() << FoundField->getType();
- Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
- << FoundField->getType();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- QualType ToType;
- TypeSourceInfo *ToTInfo;
- Expr *ToBitWidth;
- SourceLocation ToInnerLocStart;
- Expr *ToInitializer;
- if (auto Imp = importSeq(
- D->getType(), D->getTypeSourceInfo(), D->getBitWidth(),
- D->getInnerLocStart(), D->getInClassInitializer()))
- std::tie(
- ToType, ToTInfo, ToBitWidth, ToInnerLocStart, ToInitializer) = *Imp;
- else
- return Imp.takeError();
- FieldDecl *ToField;
- if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
- ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
- ToType, ToTInfo, ToBitWidth, D->isMutable(),
- D->getInClassInitStyle()))
- return ToField;
- ToField->setAccess(D->getAccess());
- ToField->setLexicalDeclContext(LexicalDC);
- if (ToInitializer)
- ToField->setInClassInitializer(ToInitializer);
- ToField->setImplicit(D->isImplicit());
- LexicalDC->addDeclInternal(ToField);
- return ToField;
- }
- ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
- // Import the major distinguishing characteristics of a variable.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Determine whether we've already imported this field.
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (auto *FoundField = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
- // For anonymous indirect fields, match up by index.
- if (!Name &&
- ASTImporter::getFieldIndex(D) !=
- ASTImporter::getFieldIndex(FoundField))
- continue;
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundField->getType(),
- !Name.isEmpty())) {
- Importer.MapImported(D, FoundField);
- return FoundField;
- }
- // If there are more anonymous fields to check, continue.
- if (!Name && I < N-1)
- continue;
- // FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
- << Name << D->getType() << FoundField->getType();
- Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
- << FoundField->getType();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- // Import the type.
- auto TypeOrErr = import(D->getType());
- if (!TypeOrErr)
- return TypeOrErr.takeError();
- auto **NamedChain =
- new (Importer.getToContext()) NamedDecl*[D->getChainingSize()];
- unsigned i = 0;
- for (auto *PI : D->chain())
- if (Expected<NamedDecl *> ToD = import(PI))
- NamedChain[i++] = *ToD;
- else
- return ToD.takeError();
- llvm::MutableArrayRef<NamedDecl *> CH = {NamedChain, D->getChainingSize()};
- IndirectFieldDecl *ToIndirectField;
- if (GetImportedOrCreateDecl(ToIndirectField, D, Importer.getToContext(), DC,
- Loc, Name.getAsIdentifierInfo(), *TypeOrErr, CH))
- // FIXME here we leak `NamedChain` which is allocated before
- return ToIndirectField;
- ToIndirectField->setAccess(D->getAccess());
- ToIndirectField->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToIndirectField);
- return ToIndirectField;
- }
- ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
- // Import the major distinguishing characteristics of a declaration.
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- // Determine whether we've already imported this decl.
- // FriendDecl is not a NamedDecl so we cannot use lookup.
- auto *RD = cast<CXXRecordDecl>(DC);
- FriendDecl *ImportedFriend = RD->getFirstFriend();
- while (ImportedFriend) {
- if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
- if (IsStructuralMatch(D->getFriendDecl(), ImportedFriend->getFriendDecl(),
- /*Complain=*/false))
- return Importer.MapImported(D, ImportedFriend);
- } else if (D->getFriendType() && ImportedFriend->getFriendType()) {
- if (Importer.IsStructurallyEquivalent(
- D->getFriendType()->getType(),
- ImportedFriend->getFriendType()->getType(), true))
- return Importer.MapImported(D, ImportedFriend);
- }
- ImportedFriend = ImportedFriend->getNextFriend();
- }
- // Not found. Create it.
- FriendDecl::FriendUnion ToFU;
- if (NamedDecl *FriendD = D->getFriendDecl()) {
- NamedDecl *ToFriendD;
- if (Error Err = importInto(ToFriendD, FriendD))
- return std::move(Err);
- if (FriendD->getFriendObjectKind() != Decl::FOK_None &&
- !(FriendD->isInIdentifierNamespace(Decl::IDNS_NonMemberOperator)))
- ToFriendD->setObjectOfFriendDecl(false);
- ToFU = ToFriendD;
- } else { // The friend is a type, not a decl.
- if (auto TSIOrErr = import(D->getFriendType()))
- ToFU = *TSIOrErr;
- else
- return TSIOrErr.takeError();
- }
- SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
- auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
- for (unsigned I = 0; I < D->NumTPLists; I++) {
- if (auto ListOrErr = import(FromTPLists[I]))
- ToTPLists[I] = *ListOrErr;
- else
- return ListOrErr.takeError();
- }
- auto LocationOrErr = import(D->getLocation());
- if (!LocationOrErr)
- return LocationOrErr.takeError();
- auto FriendLocOrErr = import(D->getFriendLoc());
- if (!FriendLocOrErr)
- return FriendLocOrErr.takeError();
- FriendDecl *FrD;
- if (GetImportedOrCreateDecl(FrD, D, Importer.getToContext(), DC,
- *LocationOrErr, ToFU,
- *FriendLocOrErr, ToTPLists))
- return FrD;
- FrD->setAccess(D->getAccess());
- FrD->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(FrD);
- return FrD;
- }
- ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
- // Import the major distinguishing characteristics of an ivar.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Determine whether we've already imported this ivar
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundIvar->getType())) {
- Importer.MapImported(D, FoundIvar);
- return FoundIvar;
- }
- Importer.ToDiag(Loc, diag::warn_odr_ivar_type_inconsistent)
- << Name << D->getType() << FoundIvar->getType();
- Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
- << FoundIvar->getType();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- Expr *ToBitWidth;
- SourceLocation ToInnerLocStart;
- if (auto Imp = importSeq(
- D->getType(), D->getTypeSourceInfo(), D->getBitWidth(), D->getInnerLocStart()))
- std::tie(ToType, ToTypeSourceInfo, ToBitWidth, ToInnerLocStart) = *Imp;
- else
- return Imp.takeError();
- ObjCIvarDecl *ToIvar;
- if (GetImportedOrCreateDecl(
- ToIvar, D, Importer.getToContext(), cast<ObjCContainerDecl>(DC),
- ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
- ToType, ToTypeSourceInfo,
- D->getAccessControl(),ToBitWidth, D->getSynthesize()))
- return ToIvar;
- ToIvar->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToIvar);
- return ToIvar;
- }
- ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
- SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
- auto RedeclIt = Redecls.begin();
- // Import the first part of the decl chain. I.e. import all previous
- // declarations starting from the canonical decl.
- for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt) {
- ExpectedDecl RedeclOrErr = import(*RedeclIt);
- if (!RedeclOrErr)
- return RedeclOrErr.takeError();
- }
- assert(*RedeclIt == D);
- // Import the major distinguishing characteristics of a variable.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Try to find a variable in our own ("to") context with the same name and
- // in the same context as the variable we're importing.
- VarDecl *FoundByLookup = nullptr;
- if (D->isFileVarDecl()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundVar = dyn_cast<VarDecl>(FoundDecl)) {
- if (!hasSameVisibilityContext(FoundVar, D))
- continue;
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundVar->getType())) {
- // The VarDecl in the "From" context has a definition, but in the
- // "To" context we already have a definition.
- VarDecl *FoundDef = FoundVar->getDefinition();
- if (D->isThisDeclarationADefinition() && FoundDef)
- // FIXME Check for ODR error if the two definitions have
- // different initializers?
- return Importer.MapImported(D, FoundDef);
- // The VarDecl in the "From" context has an initializer, but in the
- // "To" context we already have an initializer.
- const VarDecl *FoundDInit = nullptr;
- if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
- // FIXME Diagnose ODR error if the two initializers are different?
- return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
- FoundByLookup = FoundVar;
- break;
- }
- const ArrayType *FoundArray
- = Importer.getToContext().getAsArrayType(FoundVar->getType());
- const ArrayType *TArray
- = Importer.getToContext().getAsArrayType(D->getType());
- if (FoundArray && TArray) {
- if (isa<IncompleteArrayType>(FoundArray) &&
- isa<ConstantArrayType>(TArray)) {
- // Import the type.
- if (auto TyOrErr = import(D->getType()))
- FoundVar->setType(*TyOrErr);
- else
- return TyOrErr.takeError();
- FoundByLookup = FoundVar;
- break;
- } else if (isa<IncompleteArrayType>(TArray) &&
- isa<ConstantArrayType>(FoundArray)) {
- FoundByLookup = FoundVar;
- break;
- }
- }
- Importer.ToDiag(Loc, diag::warn_odr_variable_type_inconsistent)
- << Name << D->getType() << FoundVar->getType();
- Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
- << FoundVar->getType();
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceLocation ToInnerLocStart;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- D->getType(), D->getTypeSourceInfo(), D->getInnerLocStart(),
- D->getQualifierLoc()))
- std::tie(ToType, ToTypeSourceInfo, ToInnerLocStart, ToQualifierLoc) = *Imp;
- else
- return Imp.takeError();
- // Create the imported variable.
- VarDecl *ToVar;
- if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
- ToInnerLocStart, Loc,
- Name.getAsIdentifierInfo(),
- ToType, ToTypeSourceInfo,
- D->getStorageClass()))
- return ToVar;
- ToVar->setQualifierInfo(ToQualifierLoc);
- ToVar->setAccess(D->getAccess());
- ToVar->setLexicalDeclContext(LexicalDC);
- if (FoundByLookup) {
- auto *Recent = const_cast<VarDecl *>(FoundByLookup->getMostRecentDecl());
- ToVar->setPreviousDecl(Recent);
- }
- if (Error Err = ImportInitializer(D, ToVar))
- return std::move(Err);
- if (D->isConstexpr())
- ToVar->setConstexpr(true);
- if (D->getDeclContext()->containsDeclAndLoad(D))
- DC->addDeclInternal(ToVar);
- if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
- LexicalDC->addDeclInternal(ToVar);
- // Import the rest of the chain. I.e. import all subsequent declarations.
- for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
- ExpectedDecl RedeclOrErr = import(*RedeclIt);
- if (!RedeclOrErr)
- return RedeclOrErr.takeError();
- }
- return ToVar;
- }
- ExpectedDecl ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
- // Parameters are created in the translation unit's context, then moved
- // into the function declaration's context afterward.
- DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
- DeclarationName ToDeclName;
- SourceLocation ToLocation;
- QualType ToType;
- if (auto Imp = importSeq(D->getDeclName(), D->getLocation(), D->getType()))
- std::tie(ToDeclName, ToLocation, ToType) = *Imp;
- else
- return Imp.takeError();
- // Create the imported parameter.
- ImplicitParamDecl *ToParm = nullptr;
- if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
- ToLocation, ToDeclName.getAsIdentifierInfo(),
- ToType, D->getParameterKind()))
- return ToParm;
- return ToParm;
- }
- ExpectedDecl ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
- // Parameters are created in the translation unit's context, then moved
- // into the function declaration's context afterward.
- DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
- DeclarationName ToDeclName;
- SourceLocation ToLocation, ToInnerLocStart;
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- if (auto Imp = importSeq(
- D->getDeclName(), D->getLocation(), D->getType(), D->getInnerLocStart(),
- D->getTypeSourceInfo()))
- std::tie(
- ToDeclName, ToLocation, ToType, ToInnerLocStart,
- ToTypeSourceInfo) = *Imp;
- else
- return Imp.takeError();
- ParmVarDecl *ToParm;
- if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
- ToInnerLocStart, ToLocation,
- ToDeclName.getAsIdentifierInfo(), ToType,
- ToTypeSourceInfo, D->getStorageClass(),
- /*DefaultArg*/ nullptr))
- return ToParm;
- // Set the default argument.
- ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
- ToParm->setKNRPromoted(D->isKNRPromoted());
- if (D->hasUninstantiatedDefaultArg()) {
- if (auto ToDefArgOrErr = import(D->getUninstantiatedDefaultArg()))
- ToParm->setUninstantiatedDefaultArg(*ToDefArgOrErr);
- else
- return ToDefArgOrErr.takeError();
- } else if (D->hasUnparsedDefaultArg()) {
- ToParm->setUnparsedDefaultArg();
- } else if (D->hasDefaultArg()) {
- if (auto ToDefArgOrErr = import(D->getDefaultArg()))
- ToParm->setDefaultArg(*ToDefArgOrErr);
- else
- return ToDefArgOrErr.takeError();
- }
- if (D->isObjCMethodParameter()) {
- ToParm->setObjCMethodScopeInfo(D->getFunctionScopeIndex());
- ToParm->setObjCDeclQualifier(D->getObjCDeclQualifier());
- } else {
- ToParm->setScopeInfo(D->getFunctionScopeDepth(),
- D->getFunctionScopeIndex());
- }
- return ToParm;
- }
- ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
- // Import the major distinguishing characteristics of a method.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (auto *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecl)) {
- if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
- continue;
- // Check return types.
- if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
- FoundMethod->getReturnType())) {
- Importer.ToDiag(Loc, diag::warn_odr_objc_method_result_type_inconsistent)
- << D->isInstanceMethod() << Name << D->getReturnType()
- << FoundMethod->getReturnType();
- Importer.ToDiag(FoundMethod->getLocation(),
- diag::note_odr_objc_method_here)
- << D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // Check the number of parameters.
- if (D->param_size() != FoundMethod->param_size()) {
- Importer.ToDiag(Loc, diag::warn_odr_objc_method_num_params_inconsistent)
- << D->isInstanceMethod() << Name
- << D->param_size() << FoundMethod->param_size();
- Importer.ToDiag(FoundMethod->getLocation(),
- diag::note_odr_objc_method_here)
- << D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // Check parameter types.
- for (ObjCMethodDecl::param_iterator P = D->param_begin(),
- PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
- P != PEnd; ++P, ++FoundP) {
- if (!Importer.IsStructurallyEquivalent((*P)->getType(),
- (*FoundP)->getType())) {
- Importer.FromDiag((*P)->getLocation(),
- diag::warn_odr_objc_method_param_type_inconsistent)
- << D->isInstanceMethod() << Name
- << (*P)->getType() << (*FoundP)->getType();
- Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
- << (*FoundP)->getType();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- // Check variadic/non-variadic.
- // Check the number of parameters.
- if (D->isVariadic() != FoundMethod->isVariadic()) {
- Importer.ToDiag(Loc, diag::warn_odr_objc_method_variadic_inconsistent)
- << D->isInstanceMethod() << Name;
- Importer.ToDiag(FoundMethod->getLocation(),
- diag::note_odr_objc_method_here)
- << D->isInstanceMethod() << Name;
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // FIXME: Any other bits we need to merge?
- return Importer.MapImported(D, FoundMethod);
- }
- }
- SourceLocation ToEndLoc;
- QualType ToReturnType;
- TypeSourceInfo *ToReturnTypeSourceInfo;
- if (auto Imp = importSeq(
- D->getEndLoc(), D->getReturnType(), D->getReturnTypeSourceInfo()))
- std::tie(ToEndLoc, ToReturnType, ToReturnTypeSourceInfo) = *Imp;
- else
- return Imp.takeError();
- ObjCMethodDecl *ToMethod;
- if (GetImportedOrCreateDecl(
- ToMethod, D, Importer.getToContext(), Loc,
- ToEndLoc, Name.getObjCSelector(), ToReturnType,
- ToReturnTypeSourceInfo, DC, D->isInstanceMethod(), D->isVariadic(),
- D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
- D->getImplementationControl(), D->hasRelatedResultType()))
- return ToMethod;
- // FIXME: When we decide to merge method definitions, we'll need to
- // deal with implicit parameters.
- // Import the parameters
- SmallVector<ParmVarDecl *, 5> ToParams;
- for (auto *FromP : D->parameters()) {
- if (Expected<ParmVarDecl *> ToPOrErr = import(FromP))
- ToParams.push_back(*ToPOrErr);
- else
- return ToPOrErr.takeError();
- }
- // Set the parameters.
- for (auto *ToParam : ToParams) {
- ToParam->setOwningFunction(ToMethod);
- ToMethod->addDeclInternal(ToParam);
- }
- SmallVector<SourceLocation, 12> FromSelLocs;
- D->getSelectorLocs(FromSelLocs);
- SmallVector<SourceLocation, 12> ToSelLocs(FromSelLocs.size());
- if (Error Err = ImportContainerChecked(FromSelLocs, ToSelLocs))
- return std::move(Err);
- ToMethod->setMethodParams(Importer.getToContext(), ToParams, ToSelLocs);
- ToMethod->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToMethod);
- return ToMethod;
- }
- ExpectedDecl ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
- // Import the major distinguishing characteristics of a category.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- SourceLocation ToVarianceLoc, ToLocation, ToColonLoc;
- TypeSourceInfo *ToTypeSourceInfo;
- if (auto Imp = importSeq(
- D->getVarianceLoc(), D->getLocation(), D->getColonLoc(),
- D->getTypeSourceInfo()))
- std::tie(ToVarianceLoc, ToLocation, ToColonLoc, ToTypeSourceInfo) = *Imp;
- else
- return Imp.takeError();
- ObjCTypeParamDecl *Result;
- if (GetImportedOrCreateDecl(
- Result, D, Importer.getToContext(), DC, D->getVariance(),
- ToVarianceLoc, D->getIndex(),
- ToLocation, Name.getAsIdentifierInfo(),
- ToColonLoc, ToTypeSourceInfo))
- return Result;
- Result->setLexicalDeclContext(LexicalDC);
- return Result;
- }
- ExpectedDecl ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
- // Import the major distinguishing characteristics of a category.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- ObjCInterfaceDecl *ToInterface;
- if (Error Err = importInto(ToInterface, D->getClassInterface()))
- return std::move(Err);
- // Determine if we've already encountered this category.
- ObjCCategoryDecl *MergeWithCategory
- = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
- ObjCCategoryDecl *ToCategory = MergeWithCategory;
- if (!ToCategory) {
- SourceLocation ToAtStartLoc, ToCategoryNameLoc;
- SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
- if (auto Imp = importSeq(
- D->getAtStartLoc(), D->getCategoryNameLoc(),
- D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
- std::tie(
- ToAtStartLoc, ToCategoryNameLoc,
- ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
- else
- return Imp.takeError();
- if (GetImportedOrCreateDecl(ToCategory, D, Importer.getToContext(), DC,
- ToAtStartLoc, Loc,
- ToCategoryNameLoc,
- Name.getAsIdentifierInfo(), ToInterface,
- /*TypeParamList=*/nullptr,
- ToIvarLBraceLoc,
- ToIvarRBraceLoc))
- return ToCategory;
- ToCategory->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToCategory);
- // Import the type parameter list after MapImported, to avoid
- // loops when bringing in their DeclContext.
- if (auto PListOrErr = ImportObjCTypeParamList(D->getTypeParamList()))
- ToCategory->setTypeParamList(*PListOrErr);
- else
- return PListOrErr.takeError();
- // Import protocols
- SmallVector<ObjCProtocolDecl *, 4> Protocols;
- SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCCategoryDecl::protocol_loc_iterator FromProtoLoc
- = D->protocol_loc_begin();
- for (ObjCCategoryDecl::protocol_iterator FromProto = D->protocol_begin(),
- FromProtoEnd = D->protocol_end();
- FromProto != FromProtoEnd;
- ++FromProto, ++FromProtoLoc) {
- if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
- Protocols.push_back(*ToProtoOrErr);
- else
- return ToProtoOrErr.takeError();
- if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
- ProtocolLocs.push_back(*ToProtoLocOrErr);
- else
- return ToProtoLocOrErr.takeError();
- }
- // FIXME: If we're merging, make sure that the protocol list is the same.
- ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
- ProtocolLocs.data(), Importer.getToContext());
- } else {
- Importer.MapImported(D, ToCategory);
- }
- // Import all of the members of this category.
- if (Error Err = ImportDeclContext(D))
- return std::move(Err);
- // If we have an implementation, import it as well.
- if (D->getImplementation()) {
- if (Expected<ObjCCategoryImplDecl *> ToImplOrErr =
- import(D->getImplementation()))
- ToCategory->setImplementation(*ToImplOrErr);
- else
- return ToImplOrErr.takeError();
- }
- return ToCategory;
- }
- Error ASTNodeImporter::ImportDefinition(
- ObjCProtocolDecl *From, ObjCProtocolDecl *To, ImportDefinitionKind Kind) {
- if (To->getDefinition()) {
- if (shouldForceImportDeclContext(Kind))
- if (Error Err = ImportDeclContext(From))
- return Err;
- return Error::success();
- }
- // Start the protocol definition
- To->startDefinition();
- // Import protocols
- SmallVector<ObjCProtocolDecl *, 4> Protocols;
- SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCProtocolDecl::protocol_loc_iterator FromProtoLoc =
- From->protocol_loc_begin();
- for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
- FromProtoEnd = From->protocol_end();
- FromProto != FromProtoEnd;
- ++FromProto, ++FromProtoLoc) {
- if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
- Protocols.push_back(*ToProtoOrErr);
- else
- return ToProtoOrErr.takeError();
- if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
- ProtocolLocs.push_back(*ToProtoLocOrErr);
- else
- return ToProtoLocOrErr.takeError();
- }
- // FIXME: If we're merging, make sure that the protocol list is the same.
- To->setProtocolList(Protocols.data(), Protocols.size(),
- ProtocolLocs.data(), Importer.getToContext());
- if (shouldForceImportDeclContext(Kind)) {
- // Import all of the members of this protocol.
- if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
- return Err;
- }
- return Error::success();
- }
- ExpectedDecl ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
- // If this protocol has a definition in the translation unit we're coming
- // from, but this particular declaration is not that definition, import the
- // definition and map to that.
- ObjCProtocolDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
- // Import the major distinguishing characteristics of a protocol.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- ObjCProtocolDecl *MergeWithProtocol = nullptr;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
- continue;
- if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecl)))
- break;
- }
- ObjCProtocolDecl *ToProto = MergeWithProtocol;
- if (!ToProto) {
- auto ToAtBeginLocOrErr = import(D->getAtStartLoc());
- if (!ToAtBeginLocOrErr)
- return ToAtBeginLocOrErr.takeError();
- if (GetImportedOrCreateDecl(ToProto, D, Importer.getToContext(), DC,
- Name.getAsIdentifierInfo(), Loc,
- *ToAtBeginLocOrErr,
- /*PrevDecl=*/nullptr))
- return ToProto;
- ToProto->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToProto);
- }
- Importer.MapImported(D, ToProto);
- if (D->isThisDeclarationADefinition())
- if (Error Err = ImportDefinition(D, ToProto))
- return std::move(Err);
- return ToProto;
- }
- ExpectedDecl ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- ExpectedSLoc ExternLocOrErr = import(D->getExternLoc());
- if (!ExternLocOrErr)
- return ExternLocOrErr.takeError();
- ExpectedSLoc LangLocOrErr = import(D->getLocation());
- if (!LangLocOrErr)
- return LangLocOrErr.takeError();
- bool HasBraces = D->hasBraces();
- LinkageSpecDecl *ToLinkageSpec;
- if (GetImportedOrCreateDecl(ToLinkageSpec, D, Importer.getToContext(), DC,
- *ExternLocOrErr, *LangLocOrErr,
- D->getLanguage(), HasBraces))
- return ToLinkageSpec;
- if (HasBraces) {
- ExpectedSLoc RBraceLocOrErr = import(D->getRBraceLoc());
- if (!RBraceLocOrErr)
- return RBraceLocOrErr.takeError();
- ToLinkageSpec->setRBraceLoc(*RBraceLocOrErr);
- }
- ToLinkageSpec->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToLinkageSpec);
- return ToLinkageSpec;
- }
- ExpectedDecl ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD = nullptr;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- SourceLocation ToLoc, ToUsingLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc()))
- std::tie(ToLoc, ToUsingLoc, ToQualifierLoc) = *Imp;
- else
- return Imp.takeError();
- DeclarationNameInfo NameInfo(Name, ToLoc);
- if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
- return std::move(Err);
- UsingDecl *ToUsing;
- if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
- ToUsingLoc, ToQualifierLoc, NameInfo,
- D->hasTypename()))
- return ToUsing;
- ToUsing->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToUsing);
- if (NamedDecl *FromPattern =
- Importer.getFromContext().getInstantiatedFromUsingDecl(D)) {
- if (Expected<NamedDecl *> ToPatternOrErr = import(FromPattern))
- Importer.getToContext().setInstantiatedFromUsingDecl(
- ToUsing, *ToPatternOrErr);
- else
- return ToPatternOrErr.takeError();
- }
- for (UsingShadowDecl *FromShadow : D->shadows()) {
- if (Expected<UsingShadowDecl *> ToShadowOrErr = import(FromShadow))
- ToUsing->addShadowDecl(*ToShadowOrErr);
- else
- // FIXME: We return error here but the definition is already created
- // and available with lookups. How to fix this?..
- return ToShadowOrErr.takeError();
- }
- return ToUsing;
- }
- ExpectedDecl ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD = nullptr;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- Expected<UsingDecl *> ToUsingOrErr = import(D->getUsingDecl());
- if (!ToUsingOrErr)
- return ToUsingOrErr.takeError();
- Expected<NamedDecl *> ToTargetOrErr = import(D->getTargetDecl());
- if (!ToTargetOrErr)
- return ToTargetOrErr.takeError();
- UsingShadowDecl *ToShadow;
- if (GetImportedOrCreateDecl(ToShadow, D, Importer.getToContext(), DC, Loc,
- *ToUsingOrErr, *ToTargetOrErr))
- return ToShadow;
- ToShadow->setLexicalDeclContext(LexicalDC);
- ToShadow->setAccess(D->getAccess());
- if (UsingShadowDecl *FromPattern =
- Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) {
- if (Expected<UsingShadowDecl *> ToPatternOrErr = import(FromPattern))
- Importer.getToContext().setInstantiatedFromUsingShadowDecl(
- ToShadow, *ToPatternOrErr);
- else
- // FIXME: We return error here but the definition is already created
- // and available with lookups. How to fix this?..
- return ToPatternOrErr.takeError();
- }
- LexicalDC->addDeclInternal(ToShadow);
- return ToShadow;
- }
- ExpectedDecl ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD = nullptr;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- auto ToComAncestorOrErr = Importer.ImportContext(D->getCommonAncestor());
- if (!ToComAncestorOrErr)
- return ToComAncestorOrErr.takeError();
- NamespaceDecl *ToNominatedNamespace;
- SourceLocation ToUsingLoc, ToNamespaceKeyLocation, ToIdentLocation;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- D->getNominatedNamespace(), D->getUsingLoc(),
- D->getNamespaceKeyLocation(), D->getQualifierLoc(),
- D->getIdentLocation()))
- std::tie(
- ToNominatedNamespace, ToUsingLoc, ToNamespaceKeyLocation,
- ToQualifierLoc, ToIdentLocation) = *Imp;
- else
- return Imp.takeError();
- UsingDirectiveDecl *ToUsingDir;
- if (GetImportedOrCreateDecl(ToUsingDir, D, Importer.getToContext(), DC,
- ToUsingLoc,
- ToNamespaceKeyLocation,
- ToQualifierLoc,
- ToIdentLocation,
- ToNominatedNamespace, *ToComAncestorOrErr))
- return ToUsingDir;
- ToUsingDir->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToUsingDir);
- return ToUsingDir;
- }
- ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingValueDecl(
- UnresolvedUsingValueDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD = nullptr;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- SourceLocation ToLoc, ToUsingLoc, ToEllipsisLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc(),
- D->getEllipsisLoc()))
- std::tie(ToLoc, ToUsingLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
- else
- return Imp.takeError();
- DeclarationNameInfo NameInfo(Name, ToLoc);
- if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
- return std::move(Err);
- UnresolvedUsingValueDecl *ToUsingValue;
- if (GetImportedOrCreateDecl(ToUsingValue, D, Importer.getToContext(), DC,
- ToUsingLoc, ToQualifierLoc, NameInfo,
- ToEllipsisLoc))
- return ToUsingValue;
- ToUsingValue->setAccess(D->getAccess());
- ToUsingValue->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToUsingValue);
- return ToUsingValue;
- }
- ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
- UnresolvedUsingTypenameDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD = nullptr;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- SourceLocation ToUsingLoc, ToTypenameLoc, ToEllipsisLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- if (auto Imp = importSeq(
- D->getUsingLoc(), D->getTypenameLoc(), D->getQualifierLoc(),
- D->getEllipsisLoc()))
- std::tie(ToUsingLoc, ToTypenameLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
- else
- return Imp.takeError();
- UnresolvedUsingTypenameDecl *ToUsing;
- if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
- ToUsingLoc, ToTypenameLoc,
- ToQualifierLoc, Loc, Name, ToEllipsisLoc))
- return ToUsing;
- ToUsing->setAccess(D->getAccess());
- ToUsing->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToUsing);
- return ToUsing;
- }
- Error ASTNodeImporter::ImportDefinition(
- ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, ImportDefinitionKind Kind) {
- if (To->getDefinition()) {
- // Check consistency of superclass.
- ObjCInterfaceDecl *FromSuper = From->getSuperClass();
- if (FromSuper) {
- if (auto FromSuperOrErr = import(FromSuper))
- FromSuper = *FromSuperOrErr;
- else
- return FromSuperOrErr.takeError();
- }
- ObjCInterfaceDecl *ToSuper = To->getSuperClass();
- if ((bool)FromSuper != (bool)ToSuper ||
- (FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
- Importer.ToDiag(To->getLocation(),
- diag::warn_odr_objc_superclass_inconsistent)
- << To->getDeclName();
- if (ToSuper)
- Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
- << To->getSuperClass()->getDeclName();
- else
- Importer.ToDiag(To->getLocation(),
- diag::note_odr_objc_missing_superclass);
- if (From->getSuperClass())
- Importer.FromDiag(From->getSuperClassLoc(),
- diag::note_odr_objc_superclass)
- << From->getSuperClass()->getDeclName();
- else
- Importer.FromDiag(From->getLocation(),
- diag::note_odr_objc_missing_superclass);
- }
- if (shouldForceImportDeclContext(Kind))
- if (Error Err = ImportDeclContext(From))
- return Err;
- return Error::success();
- }
- // Start the definition.
- To->startDefinition();
- // If this class has a superclass, import it.
- if (From->getSuperClass()) {
- if (auto SuperTInfoOrErr = import(From->getSuperClassTInfo()))
- To->setSuperClass(*SuperTInfoOrErr);
- else
- return SuperTInfoOrErr.takeError();
- }
- // Import protocols
- SmallVector<ObjCProtocolDecl *, 4> Protocols;
- SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCInterfaceDecl::protocol_loc_iterator FromProtoLoc =
- From->protocol_loc_begin();
- for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
- FromProtoEnd = From->protocol_end();
- FromProto != FromProtoEnd;
- ++FromProto, ++FromProtoLoc) {
- if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
- Protocols.push_back(*ToProtoOrErr);
- else
- return ToProtoOrErr.takeError();
- if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
- ProtocolLocs.push_back(*ToProtoLocOrErr);
- else
- return ToProtoLocOrErr.takeError();
- }
- // FIXME: If we're merging, make sure that the protocol list is the same.
- To->setProtocolList(Protocols.data(), Protocols.size(),
- ProtocolLocs.data(), Importer.getToContext());
- // Import categories. When the categories themselves are imported, they'll
- // hook themselves into this interface.
- for (auto *Cat : From->known_categories()) {
- auto ToCatOrErr = import(Cat);
- if (!ToCatOrErr)
- return ToCatOrErr.takeError();
- }
- // If we have an @implementation, import it as well.
- if (From->getImplementation()) {
- if (Expected<ObjCImplementationDecl *> ToImplOrErr =
- import(From->getImplementation()))
- To->setImplementation(*ToImplOrErr);
- else
- return ToImplOrErr.takeError();
- }
- if (shouldForceImportDeclContext(Kind)) {
- // Import all of the members of this class.
- if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
- return Err;
- }
- return Error::success();
- }
- Expected<ObjCTypeParamList *>
- ASTNodeImporter::ImportObjCTypeParamList(ObjCTypeParamList *list) {
- if (!list)
- return nullptr;
- SmallVector<ObjCTypeParamDecl *, 4> toTypeParams;
- for (auto *fromTypeParam : *list) {
- if (auto toTypeParamOrErr = import(fromTypeParam))
- toTypeParams.push_back(*toTypeParamOrErr);
- else
- return toTypeParamOrErr.takeError();
- }
- auto LAngleLocOrErr = import(list->getLAngleLoc());
- if (!LAngleLocOrErr)
- return LAngleLocOrErr.takeError();
- auto RAngleLocOrErr = import(list->getRAngleLoc());
- if (!RAngleLocOrErr)
- return RAngleLocOrErr.takeError();
- return ObjCTypeParamList::create(Importer.getToContext(),
- *LAngleLocOrErr,
- toTypeParams,
- *RAngleLocOrErr);
- }
- ExpectedDecl ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
- // If this class has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- ObjCInterfaceDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
- // Import the major distinguishing characteristics of an @interface.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Look for an existing interface with the same name.
- ObjCInterfaceDecl *MergeWithIface = nullptr;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
- continue;
- if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecl)))
- break;
- }
- // Create an interface declaration, if one does not already exist.
- ObjCInterfaceDecl *ToIface = MergeWithIface;
- if (!ToIface) {
- ExpectedSLoc AtBeginLocOrErr = import(D->getAtStartLoc());
- if (!AtBeginLocOrErr)
- return AtBeginLocOrErr.takeError();
- if (GetImportedOrCreateDecl(
- ToIface, D, Importer.getToContext(), DC,
- *AtBeginLocOrErr, Name.getAsIdentifierInfo(),
- /*TypeParamList=*/nullptr,
- /*PrevDecl=*/nullptr, Loc, D->isImplicitInterfaceDecl()))
- return ToIface;
- ToIface->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToIface);
- }
- Importer.MapImported(D, ToIface);
- // Import the type parameter list after MapImported, to avoid
- // loops when bringing in their DeclContext.
- if (auto ToPListOrErr =
- ImportObjCTypeParamList(D->getTypeParamListAsWritten()))
- ToIface->setTypeParamList(*ToPListOrErr);
- else
- return ToPListOrErr.takeError();
- if (D->isThisDeclarationADefinition())
- if (Error Err = ImportDefinition(D, ToIface))
- return std::move(Err);
- return ToIface;
- }
- ExpectedDecl
- ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- ObjCCategoryDecl *Category;
- if (Error Err = importInto(Category, D->getCategoryDecl()))
- return std::move(Err);
- ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
- if (!ToImpl) {
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- SourceLocation ToLocation, ToAtStartLoc, ToCategoryNameLoc;
- if (auto Imp = importSeq(
- D->getLocation(), D->getAtStartLoc(), D->getCategoryNameLoc()))
- std::tie(ToLocation, ToAtStartLoc, ToCategoryNameLoc) = *Imp;
- else
- return Imp.takeError();
- if (GetImportedOrCreateDecl(
- ToImpl, D, Importer.getToContext(), DC,
- Importer.Import(D->getIdentifier()), Category->getClassInterface(),
- ToLocation, ToAtStartLoc, ToCategoryNameLoc))
- return ToImpl;
- ToImpl->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToImpl);
- Category->setImplementation(ToImpl);
- }
- Importer.MapImported(D, ToImpl);
- if (Error Err = ImportDeclContext(D))
- return std::move(Err);
- return ToImpl;
- }
- ExpectedDecl
- ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
- // Find the corresponding interface.
- ObjCInterfaceDecl *Iface;
- if (Error Err = importInto(Iface, D->getClassInterface()))
- return std::move(Err);
- // Import the superclass, if any.
- ObjCInterfaceDecl *Super;
- if (Error Err = importInto(Super, D->getSuperClass()))
- return std::move(Err);
- ObjCImplementationDecl *Impl = Iface->getImplementation();
- if (!Impl) {
- // We haven't imported an implementation yet. Create a new @implementation
- // now.
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- SourceLocation ToLocation, ToAtStartLoc, ToSuperClassLoc;
- SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
- if (auto Imp = importSeq(
- D->getLocation(), D->getAtStartLoc(), D->getSuperClassLoc(),
- D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
- std::tie(
- ToLocation, ToAtStartLoc, ToSuperClassLoc,
- ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
- else
- return Imp.takeError();
- if (GetImportedOrCreateDecl(Impl, D, Importer.getToContext(),
- DC, Iface, Super,
- ToLocation,
- ToAtStartLoc,
- ToSuperClassLoc,
- ToIvarLBraceLoc,
- ToIvarRBraceLoc))
- return Impl;
- Impl->setLexicalDeclContext(LexicalDC);
- // Associate the implementation with the class it implements.
- Iface->setImplementation(Impl);
- Importer.MapImported(D, Iface->getImplementation());
- } else {
- Importer.MapImported(D, Iface->getImplementation());
- // Verify that the existing @implementation has the same superclass.
- if ((Super && !Impl->getSuperClass()) ||
- (!Super && Impl->getSuperClass()) ||
- (Super && Impl->getSuperClass() &&
- !declaresSameEntity(Super->getCanonicalDecl(),
- Impl->getSuperClass()))) {
- Importer.ToDiag(Impl->getLocation(),
- diag::warn_odr_objc_superclass_inconsistent)
- << Iface->getDeclName();
- // FIXME: It would be nice to have the location of the superclass
- // below.
- if (Impl->getSuperClass())
- Importer.ToDiag(Impl->getLocation(),
- diag::note_odr_objc_superclass)
- << Impl->getSuperClass()->getDeclName();
- else
- Importer.ToDiag(Impl->getLocation(),
- diag::note_odr_objc_missing_superclass);
- if (D->getSuperClass())
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_superclass)
- << D->getSuperClass()->getDeclName();
- else
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_missing_superclass);
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- // Import all of the members of this @implementation.
- if (Error Err = ImportDeclContext(D))
- return std::move(Err);
- return Impl;
- }
- ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
- // Import the major distinguishing characteristics of an @property.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // Check whether we have already imported this property.
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (auto *FoundProp = dyn_cast<ObjCPropertyDecl>(FoundDecl)) {
- // Check property types.
- if (!Importer.IsStructurallyEquivalent(D->getType(),
- FoundProp->getType())) {
- Importer.ToDiag(Loc, diag::warn_odr_objc_property_type_inconsistent)
- << Name << D->getType() << FoundProp->getType();
- Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
- << FoundProp->getType();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // FIXME: Check property attributes, getters, setters, etc.?
- // Consider these properties to be equivalent.
- Importer.MapImported(D, FoundProp);
- return FoundProp;
- }
- }
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceLocation ToAtLoc, ToLParenLoc;
- if (auto Imp = importSeq(
- D->getType(), D->getTypeSourceInfo(), D->getAtLoc(), D->getLParenLoc()))
- std::tie(ToType, ToTypeSourceInfo, ToAtLoc, ToLParenLoc) = *Imp;
- else
- return Imp.takeError();
- // Create the new property.
- ObjCPropertyDecl *ToProperty;
- if (GetImportedOrCreateDecl(
- ToProperty, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(), ToAtLoc,
- ToLParenLoc, ToType,
- ToTypeSourceInfo, D->getPropertyImplementation()))
- return ToProperty;
- Selector ToGetterName, ToSetterName;
- SourceLocation ToGetterNameLoc, ToSetterNameLoc;
- ObjCMethodDecl *ToGetterMethodDecl, *ToSetterMethodDecl;
- ObjCIvarDecl *ToPropertyIvarDecl;
- if (auto Imp = importSeq(
- D->getGetterName(), D->getSetterName(),
- D->getGetterNameLoc(), D->getSetterNameLoc(),
- D->getGetterMethodDecl(), D->getSetterMethodDecl(),
- D->getPropertyIvarDecl()))
- std::tie(
- ToGetterName, ToSetterName,
- ToGetterNameLoc, ToSetterNameLoc,
- ToGetterMethodDecl, ToSetterMethodDecl,
- ToPropertyIvarDecl) = *Imp;
- else
- return Imp.takeError();
- ToProperty->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToProperty);
- ToProperty->setPropertyAttributes(D->getPropertyAttributes());
- ToProperty->setPropertyAttributesAsWritten(
- D->getPropertyAttributesAsWritten());
- ToProperty->setGetterName(ToGetterName, ToGetterNameLoc);
- ToProperty->setSetterName(ToSetterName, ToSetterNameLoc);
- ToProperty->setGetterMethodDecl(ToGetterMethodDecl);
- ToProperty->setSetterMethodDecl(ToSetterMethodDecl);
- ToProperty->setPropertyIvarDecl(ToPropertyIvarDecl);
- return ToProperty;
- }
- ExpectedDecl
- ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- ObjCPropertyDecl *Property;
- if (Error Err = importInto(Property, D->getPropertyDecl()))
- return std::move(Err);
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- auto *InImpl = cast<ObjCImplDecl>(LexicalDC);
- // Import the ivar (for an @synthesize).
- ObjCIvarDecl *Ivar = nullptr;
- if (Error Err = importInto(Ivar, D->getPropertyIvarDecl()))
- return std::move(Err);
- ObjCPropertyImplDecl *ToImpl
- = InImpl->FindPropertyImplDecl(Property->getIdentifier(),
- Property->getQueryKind());
- if (!ToImpl) {
- SourceLocation ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc;
- if (auto Imp = importSeq(
- D->getBeginLoc(), D->getLocation(), D->getPropertyIvarDeclLoc()))
- std::tie(ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc) = *Imp;
- else
- return Imp.takeError();
- if (GetImportedOrCreateDecl(ToImpl, D, Importer.getToContext(), DC,
- ToBeginLoc,
- ToLocation, Property,
- D->getPropertyImplementation(), Ivar,
- ToPropertyIvarDeclLoc))
- return ToImpl;
- ToImpl->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToImpl);
- } else {
- // Check that we have the same kind of property implementation (@synthesize
- // vs. @dynamic).
- if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
- Importer.ToDiag(ToImpl->getLocation(),
- diag::warn_odr_objc_property_impl_kind_inconsistent)
- << Property->getDeclName()
- << (ToImpl->getPropertyImplementation()
- == ObjCPropertyImplDecl::Dynamic);
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_property_impl_kind)
- << D->getPropertyDecl()->getDeclName()
- << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // For @synthesize, check that we have the same
- if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
- Ivar != ToImpl->getPropertyIvarDecl()) {
- Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
- diag::warn_odr_objc_synthesize_ivar_inconsistent)
- << Property->getDeclName()
- << ToImpl->getPropertyIvarDecl()->getDeclName()
- << Ivar->getDeclName();
- Importer.FromDiag(D->getPropertyIvarDeclLoc(),
- diag::note_odr_objc_synthesize_ivar_here)
- << D->getPropertyIvarDecl()->getDeclName();
- return make_error<ImportError>(ImportError::NameConflict);
- }
- // Merge the existing implementation with the new implementation.
- Importer.MapImported(D, ToImpl);
- }
- return ToImpl;
- }
- ExpectedDecl
- ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
- // For template arguments, we adopt the translation unit as our declaration
- // context. This context will be fixed when the actual template declaration
- // is created.
- // FIXME: Import default argument.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc LocationOrErr = import(D->getLocation());
- if (!LocationOrErr)
- return LocationOrErr.takeError();
- TemplateTypeParmDecl *ToD = nullptr;
- (void)GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- *BeginLocOrErr, *LocationOrErr,
- D->getDepth(), D->getIndex(), Importer.Import(D->getIdentifier()),
- D->wasDeclaredWithTypename(), D->isParameterPack());
- return ToD;
- }
- ExpectedDecl
- ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- DeclarationName ToDeclName;
- SourceLocation ToLocation, ToInnerLocStart;
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- if (auto Imp = importSeq(
- D->getDeclName(), D->getLocation(), D->getType(), D->getTypeSourceInfo(),
- D->getInnerLocStart()))
- std::tie(
- ToDeclName, ToLocation, ToType, ToTypeSourceInfo,
- ToInnerLocStart) = *Imp;
- else
- return Imp.takeError();
- // FIXME: Import default argument.
- NonTypeTemplateParmDecl *ToD = nullptr;
- (void)GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- ToInnerLocStart, ToLocation, D->getDepth(),
- D->getPosition(), ToDeclName.getAsIdentifierInfo(), ToType,
- D->isParameterPack(), ToTypeSourceInfo);
- return ToD;
- }
- ExpectedDecl
- ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
- // Import the name of this declaration.
- auto NameOrErr = import(D->getDeclName());
- if (!NameOrErr)
- return NameOrErr.takeError();
- // Import the location of this declaration.
- ExpectedSLoc LocationOrErr = import(D->getLocation());
- if (!LocationOrErr)
- return LocationOrErr.takeError();
- // Import template parameters.
- auto TemplateParamsOrErr = import(D->getTemplateParameters());
- if (!TemplateParamsOrErr)
- return TemplateParamsOrErr.takeError();
- // FIXME: Import default argument.
- TemplateTemplateParmDecl *ToD = nullptr;
- (void)GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr,
- D->getDepth(), D->getPosition(), D->isParameterPack(),
- (*NameOrErr).getAsIdentifierInfo(),
- *TemplateParamsOrErr);
- return ToD;
- }
- // Returns the definition for a (forward) declaration of a TemplateDecl, if
- // it has any definition in the redecl chain.
- template <typename T> static auto getTemplateDefinition(T *D) -> T * {
- assert(D->getTemplatedDecl() && "Should be called on templates only");
- auto *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
- if (!ToTemplatedDef)
- return nullptr;
- auto *TemplateWithDef = ToTemplatedDef->getDescribedTemplate();
- return cast_or_null<T>(TemplateWithDef);
- }
- ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
- bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
- // Import the major distinguishing characteristics of this class template.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- ClassTemplateDecl *FoundByLookup = nullptr;
- // We may already have a template of the same name; try to find and match it.
- if (!DC->isFunctionOrMethod()) {
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary |
- Decl::IDNS_TagFriend))
- continue;
- Decl *Found = FoundDecl;
- auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found);
- if (FoundTemplate) {
- if (IsStructuralMatch(D, FoundTemplate)) {
- ClassTemplateDecl *TemplateWithDef =
- getTemplateDefinition(FoundTemplate);
- if (D->isThisDeclarationADefinition() && TemplateWithDef) {
- return Importer.MapImported(D, TemplateWithDef);
- }
- FoundByLookup = FoundTemplate;
- break;
- }
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- }
- if (!Name)
- return make_error<ImportError>(ImportError::NameConflict);
- }
- CXXRecordDecl *FromTemplated = D->getTemplatedDecl();
- // Create the declaration that is being templated.
- CXXRecordDecl *ToTemplated;
- if (Error Err = importInto(ToTemplated, FromTemplated))
- return std::move(Err);
- // Create the class template declaration itself.
- auto TemplateParamsOrErr = import(D->getTemplateParameters());
- if (!TemplateParamsOrErr)
- return TemplateParamsOrErr.takeError();
- ClassTemplateDecl *D2;
- if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name,
- *TemplateParamsOrErr, ToTemplated))
- return D2;
- ToTemplated->setDescribedClassTemplate(D2);
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- if (D->getDeclContext()->containsDeclAndLoad(D))
- DC->addDeclInternal(D2);
- if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
- LexicalDC->addDeclInternal(D2);
- if (FoundByLookup) {
- auto *Recent =
- const_cast<ClassTemplateDecl *>(FoundByLookup->getMostRecentDecl());
- // It is possible that during the import of the class template definition
- // we start the import of a fwd friend decl of the very same class template
- // and we add the fwd friend decl to the lookup table. But the ToTemplated
- // had been created earlier and by that time the lookup could not find
- // anything existing, so it has no previous decl. Later, (still during the
- // import of the fwd friend decl) we start to import the definition again
- // and this time the lookup finds the previous fwd friend class template.
- // In this case we must set up the previous decl for the templated decl.
- if (!ToTemplated->getPreviousDecl()) {
- assert(FoundByLookup->getTemplatedDecl() &&
- "Found decl must have its templated decl set");
- CXXRecordDecl *PrevTemplated =
- FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
- if (ToTemplated != PrevTemplated)
- ToTemplated->setPreviousDecl(PrevTemplated);
- }
- D2->setPreviousDecl(Recent);
- }
- if (LexicalDC != DC && IsFriend)
- DC->makeDeclVisibleInContext(D2);
- if (FromTemplated->isCompleteDefinition() &&
- !ToTemplated->isCompleteDefinition()) {
- // FIXME: Import definition!
- }
- return D2;
- }
- ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
- ClassTemplateSpecializationDecl *D) {
- ClassTemplateDecl *ClassTemplate;
- if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
- return std::move(Err);
- // Import the context of this declaration.
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- // Import template arguments.
- SmallVector<TemplateArgument, 2> TemplateArgs;
- if (Error Err = ImportTemplateArguments(
- D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
- return std::move(Err);
- // Try to find an existing specialization with these template arguments.
- void *InsertPos = nullptr;
- ClassTemplateSpecializationDecl *PrevDecl = nullptr;
- ClassTemplatePartialSpecializationDecl *PartialSpec =
- dyn_cast<ClassTemplatePartialSpecializationDecl>(D);
- if (PartialSpec)
- PrevDecl =
- ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
- else
- PrevDecl = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
- if (PrevDecl) {
- if (IsStructuralMatch(D, PrevDecl)) {
- if (D->isThisDeclarationADefinition() && PrevDecl->getDefinition()) {
- Importer.MapImported(D, PrevDecl->getDefinition());
- // Import those default field initializers which have been
- // instantiated in the "From" context, but not in the "To" context.
- for (auto *FromField : D->fields()) {
- auto ToOrErr = import(FromField);
- if (!ToOrErr)
- return ToOrErr.takeError();
- }
- // Import those methods which have been instantiated in the
- // "From" context, but not in the "To" context.
- for (CXXMethodDecl *FromM : D->methods()) {
- auto ToOrErr = import(FromM);
- if (!ToOrErr)
- return ToOrErr.takeError();
- }
- // TODO Import instantiated default arguments.
- // TODO Import instantiated exception specifications.
- //
- // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint
- // what else could be fused during an AST merge.
- return PrevDecl;
- }
- } else { // ODR violation.
- // FIXME HandleNameConflict
- return nullptr;
- }
- }
- // Import the location of this declaration.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc IdLocOrErr = import(D->getLocation());
- if (!IdLocOrErr)
- return IdLocOrErr.takeError();
- // Create the specialization.
- ClassTemplateSpecializationDecl *D2 = nullptr;
- if (PartialSpec) {
- // Import TemplateArgumentListInfo.
- TemplateArgumentListInfo ToTAInfo;
- const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
- if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
- return std::move(Err);
- QualType CanonInjType;
- if (Error Err = importInto(
- CanonInjType, PartialSpec->getInjectedSpecializationType()))
- return std::move(Err);
- CanonInjType = CanonInjType.getCanonicalType();
- auto ToTPListOrErr = import(PartialSpec->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
- if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
- llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
- ToTAInfo, CanonInjType,
- cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
- return D2;
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
- // Add this partial specialization to the class template.
- ClassTemplate->AddPartialSpecialization(
- cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
- } else { // Not a partial specialization.
- if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
- PrevDecl))
- return D2;
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
- // Add this specialization to the class template.
- ClassTemplate->AddSpecialization(D2, InsertPos);
- }
- D2->setSpecializationKind(D->getSpecializationKind());
- // Set the context of this specialization/instantiation.
- D2->setLexicalDeclContext(LexicalDC);
- // Add to the DC only if it was an explicit specialization/instantiation.
- if (D2->isExplicitInstantiationOrSpecialization()) {
- LexicalDC->addDeclInternal(D2);
- }
- // Import the qualifier, if any.
- if (auto LocOrErr = import(D->getQualifierLoc()))
- D2->setQualifierInfo(*LocOrErr);
- else
- return LocOrErr.takeError();
- if (auto *TSI = D->getTypeAsWritten()) {
- if (auto TInfoOrErr = import(TSI))
- D2->setTypeAsWritten(*TInfoOrErr);
- else
- return TInfoOrErr.takeError();
- if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
- D2->setTemplateKeywordLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- if (auto LocOrErr = import(D->getExternLoc()))
- D2->setExternLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- }
- if (D->getPointOfInstantiation().isValid()) {
- if (auto POIOrErr = import(D->getPointOfInstantiation()))
- D2->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
- D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
- if (D->isCompleteDefinition())
- if (Error Err = ImportDefinition(D, D2))
- return std::move(Err);
- return D2;
- }
- ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
- // If this variable has a definition in the translation unit we're coming
- // from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- auto *Definition =
- cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
- if (Definition && Definition != D->getTemplatedDecl()) {
- if (ExpectedDecl ImportedDefOrErr = import(
- Definition->getDescribedVarTemplate()))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
- // Import the major distinguishing characteristics of this variable template.
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- // We may already have a template of the same name; try to find and match it.
- assert(!DC->isFunctionOrMethod() &&
- "Variable templates cannot be declared at function scope");
- SmallVector<NamedDecl *, 4> ConflictingDecls;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
- continue;
- Decl *Found = FoundDecl;
- if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
- if (IsStructuralMatch(D, FoundTemplate)) {
- // The variable templates structurally match; call it the same template.
- Importer.MapImported(D->getTemplatedDecl(),
- FoundTemplate->getTemplatedDecl());
- return Importer.MapImported(D, FoundTemplate);
- }
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
- ConflictingDecls.data(),
- ConflictingDecls.size());
- }
- if (!Name)
- // FIXME: Is it possible to get other error than name conflict?
- // (Put this `if` into the previous `if`?)
- return make_error<ImportError>(ImportError::NameConflict);
- VarDecl *DTemplated = D->getTemplatedDecl();
- // Import the type.
- // FIXME: Value not used?
- ExpectedType TypeOrErr = import(DTemplated->getType());
- if (!TypeOrErr)
- return TypeOrErr.takeError();
- // Create the declaration that is being templated.
- VarDecl *ToTemplated;
- if (Error Err = importInto(ToTemplated, DTemplated))
- return std::move(Err);
- // Create the variable template declaration itself.
- auto TemplateParamsOrErr = import(D->getTemplateParameters());
- if (!TemplateParamsOrErr)
- return TemplateParamsOrErr.takeError();
- VarTemplateDecl *ToVarTD;
- if (GetImportedOrCreateDecl(ToVarTD, D, Importer.getToContext(), DC, Loc,
- Name, *TemplateParamsOrErr, ToTemplated))
- return ToVarTD;
- ToTemplated->setDescribedVarTemplate(ToVarTD);
- ToVarTD->setAccess(D->getAccess());
- ToVarTD->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToVarTD);
- if (DTemplated->isThisDeclarationADefinition() &&
- !ToTemplated->isThisDeclarationADefinition()) {
- // FIXME: Import definition!
- }
- return ToVarTD;
- }
- ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
- VarTemplateSpecializationDecl *D) {
- // If this record has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- VarDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
- VarTemplateDecl *VarTemplate = nullptr;
- if (Error Err = importInto(VarTemplate, D->getSpecializedTemplate()))
- return std::move(Err);
- // Import the context of this declaration.
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- // Import the location of this declaration.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- auto IdLocOrErr = import(D->getLocation());
- if (!IdLocOrErr)
- return IdLocOrErr.takeError();
- // Import template arguments.
- SmallVector<TemplateArgument, 2> TemplateArgs;
- if (Error Err = ImportTemplateArguments(
- D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
- return std::move(Err);
- // Try to find an existing specialization with these template arguments.
- void *InsertPos = nullptr;
- VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
- TemplateArgs, InsertPos);
- if (D2) {
- // We already have a variable template specialization with these template
- // arguments.
- // FIXME: Check for specialization vs. instantiation errors.
- if (VarDecl *FoundDef = D2->getDefinition()) {
- if (!D->isThisDeclarationADefinition() ||
- IsStructuralMatch(D, FoundDef)) {
- // The record types structurally match, or the "from" translation
- // unit only had a forward declaration anyway; call it the same
- // variable.
- return Importer.MapImported(D, FoundDef);
- }
- }
- } else {
- // Import the type.
- QualType T;
- if (Error Err = importInto(T, D->getType()))
- return std::move(Err);
- auto TInfoOrErr = import(D->getTypeSourceInfo());
- if (!TInfoOrErr)
- return TInfoOrErr.takeError();
- TemplateArgumentListInfo ToTAInfo;
- if (Error Err = ImportTemplateArgumentListInfo(
- D->getTemplateArgsInfo(), ToTAInfo))
- return std::move(Err);
- using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
- // Create a new specialization.
- if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
- // Import TemplateArgumentListInfo
- TemplateArgumentListInfo ArgInfos;
- const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
- // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
- if (Error Err = ImportTemplateArgumentListInfo(
- *FromTAArgsAsWritten, ArgInfos))
- return std::move(Err);
- auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
- PartVarSpecDecl *ToPartial;
- if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
- VarTemplate, T, *TInfoOrErr,
- D->getStorageClass(), TemplateArgs, ArgInfos))
- return ToPartial;
- if (Expected<PartVarSpecDecl *> ToInstOrErr = import(
- FromPartial->getInstantiatedFromMember()))
- ToPartial->setInstantiatedFromMember(*ToInstOrErr);
- else
- return ToInstOrErr.takeError();
- if (FromPartial->isMemberSpecialization())
- ToPartial->setMemberSpecialization();
- D2 = ToPartial;
- } else { // Full specialization
- if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
- *BeginLocOrErr, *IdLocOrErr, VarTemplate,
- T, *TInfoOrErr,
- D->getStorageClass(), TemplateArgs))
- return D2;
- }
- if (D->getPointOfInstantiation().isValid()) {
- if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation()))
- D2->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
- D2->setSpecializationKind(D->getSpecializationKind());
- D2->setTemplateArgsInfo(ToTAInfo);
- // Add this specialization to the class template.
- VarTemplate->AddSpecialization(D2, InsertPos);
- // Import the qualifier, if any.
- if (auto LocOrErr = import(D->getQualifierLoc()))
- D2->setQualifierInfo(*LocOrErr);
- else
- return LocOrErr.takeError();
- if (D->isConstexpr())
- D2->setConstexpr(true);
- // Add the specialization to this context.
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
- D2->setAccess(D->getAccess());
- }
- if (Error Err = ImportInitializer(D, D2))
- return std::move(Err);
- return D2;
- }
- ExpectedDecl
- ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- const FunctionTemplateDecl *FoundByLookup = nullptr;
- // Try to find a function in our own ("to") context with the same name, same
- // type, and in the same context as the function we're importing.
- // FIXME Split this into a separate function.
- if (!LexicalDC->isFunctionOrMethod()) {
- unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
- auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(IDNS))
- continue;
- if (auto *FoundTemplate = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
- if (FoundTemplate->hasExternalFormalLinkage() &&
- D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundTemplate)) {
- FunctionTemplateDecl *TemplateWithDef =
- getTemplateDefinition(FoundTemplate);
- if (D->isThisDeclarationADefinition() && TemplateWithDef) {
- return Importer.MapImported(D, TemplateWithDef);
- }
- FoundByLookup = FoundTemplate;
- break;
- }
- // TODO: handle conflicting names
- }
- }
- }
- }
- auto ParamsOrErr = import(D->getTemplateParameters());
- if (!ParamsOrErr)
- return ParamsOrErr.takeError();
- FunctionDecl *TemplatedFD;
- if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
- return std::move(Err);
- FunctionTemplateDecl *ToFunc;
- if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
- *ParamsOrErr, TemplatedFD))
- return ToFunc;
- TemplatedFD->setDescribedFunctionTemplate(ToFunc);
- ToFunc->setAccess(D->getAccess());
- ToFunc->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToFunc);
- if (FoundByLookup) {
- auto *Recent =
- const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl());
- if (!TemplatedFD->getPreviousDecl()) {
- assert(FoundByLookup->getTemplatedDecl() &&
- "Found decl must have its templated decl set");
- auto *PrevTemplated =
- FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
- if (TemplatedFD != PrevTemplated)
- TemplatedFD->setPreviousDecl(PrevTemplated);
- }
- ToFunc->setPreviousDecl(Recent);
- }
- return ToFunc;
- }
- //----------------------------------------------------------------------------
- // Import Statements
- //----------------------------------------------------------------------------
- ExpectedStmt ASTNodeImporter::VisitStmt(Stmt *S) {
- Importer.FromDiag(S->getBeginLoc(), diag::err_unsupported_ast_node)
- << S->getStmtClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
- SmallVector<IdentifierInfo *, 4> Names;
- for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
- IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
- // ToII is nullptr when no symbolic name is given for output operand
- // see ParseStmtAsm::ParseAsmOperandsOpt
- Names.push_back(ToII);
- }
- for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
- IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I));
- // ToII is nullptr when no symbolic name is given for input operand
- // see ParseStmtAsm::ParseAsmOperandsOpt
- Names.push_back(ToII);
- }
- SmallVector<StringLiteral *, 4> Clobbers;
- for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) {
- if (auto ClobberOrErr = import(S->getClobberStringLiteral(I)))
- Clobbers.push_back(*ClobberOrErr);
- else
- return ClobberOrErr.takeError();
- }
- SmallVector<StringLiteral *, 4> Constraints;
- for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
- if (auto OutputOrErr = import(S->getOutputConstraintLiteral(I)))
- Constraints.push_back(*OutputOrErr);
- else
- return OutputOrErr.takeError();
- }
- for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
- if (auto InputOrErr = import(S->getInputConstraintLiteral(I)))
- Constraints.push_back(*InputOrErr);
- else
- return InputOrErr.takeError();
- }
- SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs() +
- S->getNumLabels());
- if (Error Err = ImportContainerChecked(S->outputs(), Exprs))
- return std::move(Err);
- if (Error Err =
- ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
- return std::move(Err);
- if (Error Err = ImportArrayChecked(
- S->labels(), Exprs.begin() + S->getNumOutputs() + S->getNumInputs()))
- return std::move(Err);
- ExpectedSLoc AsmLocOrErr = import(S->getAsmLoc());
- if (!AsmLocOrErr)
- return AsmLocOrErr.takeError();
- auto AsmStrOrErr = import(S->getAsmString());
- if (!AsmStrOrErr)
- return AsmStrOrErr.takeError();
- ExpectedSLoc RParenLocOrErr = import(S->getRParenLoc());
- if (!RParenLocOrErr)
- return RParenLocOrErr.takeError();
- return new (Importer.getToContext()) GCCAsmStmt(
- Importer.getToContext(),
- *AsmLocOrErr,
- S->isSimple(),
- S->isVolatile(),
- S->getNumOutputs(),
- S->getNumInputs(),
- Names.data(),
- Constraints.data(),
- Exprs.data(),
- *AsmStrOrErr,
- S->getNumClobbers(),
- Clobbers.data(),
- S->getNumLabels(),
- *RParenLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
- auto Imp = importSeq(S->getDeclGroup(), S->getBeginLoc(), S->getEndLoc());
- if (!Imp)
- return Imp.takeError();
- DeclGroupRef ToDG;
- SourceLocation ToBeginLoc, ToEndLoc;
- std::tie(ToDG, ToBeginLoc, ToEndLoc) = *Imp;
- return new (Importer.getToContext()) DeclStmt(ToDG, ToBeginLoc, ToEndLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitNullStmt(NullStmt *S) {
- ExpectedSLoc ToSemiLocOrErr = import(S->getSemiLoc());
- if (!ToSemiLocOrErr)
- return ToSemiLocOrErr.takeError();
- return new (Importer.getToContext()) NullStmt(
- *ToSemiLocOrErr, S->hasLeadingEmptyMacro());
- }
- ExpectedStmt ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
- SmallVector<Stmt *, 8> ToStmts(S->size());
- if (Error Err = ImportContainerChecked(S->body(), ToStmts))
- return std::move(Err);
- ExpectedSLoc ToLBracLocOrErr = import(S->getLBracLoc());
- if (!ToLBracLocOrErr)
- return ToLBracLocOrErr.takeError();
- ExpectedSLoc ToRBracLocOrErr = import(S->getRBracLoc());
- if (!ToRBracLocOrErr)
- return ToRBracLocOrErr.takeError();
- return CompoundStmt::Create(
- Importer.getToContext(), ToStmts,
- *ToLBracLocOrErr, *ToRBracLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
- auto Imp = importSeq(
- S->getLHS(), S->getRHS(), S->getSubStmt(), S->getCaseLoc(),
- S->getEllipsisLoc(), S->getColonLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToLHS, *ToRHS;
- Stmt *ToSubStmt;
- SourceLocation ToCaseLoc, ToEllipsisLoc, ToColonLoc;
- std::tie(ToLHS, ToRHS, ToSubStmt, ToCaseLoc, ToEllipsisLoc, ToColonLoc) =
- *Imp;
- auto *ToStmt = CaseStmt::Create(Importer.getToContext(), ToLHS, ToRHS,
- ToCaseLoc, ToEllipsisLoc, ToColonLoc);
- ToStmt->setSubStmt(ToSubStmt);
- return ToStmt;
- }
- ExpectedStmt ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
- auto Imp = importSeq(S->getDefaultLoc(), S->getColonLoc(), S->getSubStmt());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToDefaultLoc, ToColonLoc;
- Stmt *ToSubStmt;
- std::tie(ToDefaultLoc, ToColonLoc, ToSubStmt) = *Imp;
- return new (Importer.getToContext()) DefaultStmt(
- ToDefaultLoc, ToColonLoc, ToSubStmt);
- }
- ExpectedStmt ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
- auto Imp = importSeq(S->getIdentLoc(), S->getDecl(), S->getSubStmt());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToIdentLoc;
- LabelDecl *ToLabelDecl;
- Stmt *ToSubStmt;
- std::tie(ToIdentLoc, ToLabelDecl, ToSubStmt) = *Imp;
- return new (Importer.getToContext()) LabelStmt(
- ToIdentLoc, ToLabelDecl, ToSubStmt);
- }
- ExpectedStmt ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
- ExpectedSLoc ToAttrLocOrErr = import(S->getAttrLoc());
- if (!ToAttrLocOrErr)
- return ToAttrLocOrErr.takeError();
- ArrayRef<const Attr*> FromAttrs(S->getAttrs());
- SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
- if (Error Err = ImportContainerChecked(FromAttrs, ToAttrs))
- return std::move(Err);
- ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
- if (!ToSubStmtOrErr)
- return ToSubStmtOrErr.takeError();
- return AttributedStmt::Create(
- Importer.getToContext(), *ToAttrLocOrErr, ToAttrs, *ToSubStmtOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitIfStmt(IfStmt *S) {
- auto Imp = importSeq(
- S->getIfLoc(), S->getInit(), S->getConditionVariable(), S->getCond(),
- S->getThen(), S->getElseLoc(), S->getElse());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToIfLoc, ToElseLoc;
- Stmt *ToInit, *ToThen, *ToElse;
- VarDecl *ToConditionVariable;
- Expr *ToCond;
- std::tie(
- ToIfLoc, ToInit, ToConditionVariable, ToCond, ToThen, ToElseLoc, ToElse) =
- *Imp;
- return IfStmt::Create(Importer.getToContext(), ToIfLoc, S->isConstexpr(),
- ToInit, ToConditionVariable, ToCond, ToThen, ToElseLoc,
- ToElse);
- }
- ExpectedStmt ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
- auto Imp = importSeq(
- S->getInit(), S->getConditionVariable(), S->getCond(),
- S->getBody(), S->getSwitchLoc());
- if (!Imp)
- return Imp.takeError();
- Stmt *ToInit, *ToBody;
- VarDecl *ToConditionVariable;
- Expr *ToCond;
- SourceLocation ToSwitchLoc;
- std::tie(ToInit, ToConditionVariable, ToCond, ToBody, ToSwitchLoc) = *Imp;
- auto *ToStmt = SwitchStmt::Create(Importer.getToContext(), ToInit,
- ToConditionVariable, ToCond);
- ToStmt->setBody(ToBody);
- ToStmt->setSwitchLoc(ToSwitchLoc);
- // Now we have to re-chain the cases.
- SwitchCase *LastChainedSwitchCase = nullptr;
- for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr;
- SC = SC->getNextSwitchCase()) {
- Expected<SwitchCase *> ToSCOrErr = import(SC);
- if (!ToSCOrErr)
- return ToSCOrErr.takeError();
- if (LastChainedSwitchCase)
- LastChainedSwitchCase->setNextSwitchCase(*ToSCOrErr);
- else
- ToStmt->setSwitchCaseList(*ToSCOrErr);
- LastChainedSwitchCase = *ToSCOrErr;
- }
- return ToStmt;
- }
- ExpectedStmt ASTNodeImporter::VisitWhileStmt(WhileStmt *S) {
- auto Imp = importSeq(
- S->getConditionVariable(), S->getCond(), S->getBody(), S->getWhileLoc());
- if (!Imp)
- return Imp.takeError();
- VarDecl *ToConditionVariable;
- Expr *ToCond;
- Stmt *ToBody;
- SourceLocation ToWhileLoc;
- std::tie(ToConditionVariable, ToCond, ToBody, ToWhileLoc) = *Imp;
- return WhileStmt::Create(Importer.getToContext(), ToConditionVariable, ToCond,
- ToBody, ToWhileLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) {
- auto Imp = importSeq(
- S->getBody(), S->getCond(), S->getDoLoc(), S->getWhileLoc(),
- S->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- Stmt *ToBody;
- Expr *ToCond;
- SourceLocation ToDoLoc, ToWhileLoc, ToRParenLoc;
- std::tie(ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc) = *Imp;
- return new (Importer.getToContext()) DoStmt(
- ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitForStmt(ForStmt *S) {
- auto Imp = importSeq(
- S->getInit(), S->getCond(), S->getConditionVariable(), S->getInc(),
- S->getBody(), S->getForLoc(), S->getLParenLoc(), S->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- Stmt *ToInit;
- Expr *ToCond, *ToInc;
- VarDecl *ToConditionVariable;
- Stmt *ToBody;
- SourceLocation ToForLoc, ToLParenLoc, ToRParenLoc;
- std::tie(
- ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc,
- ToLParenLoc, ToRParenLoc) = *Imp;
- return new (Importer.getToContext()) ForStmt(
- Importer.getToContext(),
- ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc, ToLParenLoc,
- ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
- auto Imp = importSeq(S->getLabel(), S->getGotoLoc(), S->getLabelLoc());
- if (!Imp)
- return Imp.takeError();
- LabelDecl *ToLabel;
- SourceLocation ToGotoLoc, ToLabelLoc;
- std::tie(ToLabel, ToGotoLoc, ToLabelLoc) = *Imp;
- return new (Importer.getToContext()) GotoStmt(
- ToLabel, ToGotoLoc, ToLabelLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
- auto Imp = importSeq(S->getGotoLoc(), S->getStarLoc(), S->getTarget());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToGotoLoc, ToStarLoc;
- Expr *ToTarget;
- std::tie(ToGotoLoc, ToStarLoc, ToTarget) = *Imp;
- return new (Importer.getToContext()) IndirectGotoStmt(
- ToGotoLoc, ToStarLoc, ToTarget);
- }
- ExpectedStmt ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
- ExpectedSLoc ToContinueLocOrErr = import(S->getContinueLoc());
- if (!ToContinueLocOrErr)
- return ToContinueLocOrErr.takeError();
- return new (Importer.getToContext()) ContinueStmt(*ToContinueLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
- auto ToBreakLocOrErr = import(S->getBreakLoc());
- if (!ToBreakLocOrErr)
- return ToBreakLocOrErr.takeError();
- return new (Importer.getToContext()) BreakStmt(*ToBreakLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
- auto Imp = importSeq(
- S->getReturnLoc(), S->getRetValue(), S->getNRVOCandidate());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToReturnLoc;
- Expr *ToRetValue;
- const VarDecl *ToNRVOCandidate;
- std::tie(ToReturnLoc, ToRetValue, ToNRVOCandidate) = *Imp;
- return ReturnStmt::Create(Importer.getToContext(), ToReturnLoc, ToRetValue,
- ToNRVOCandidate);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
- auto Imp = importSeq(
- S->getCatchLoc(), S->getExceptionDecl(), S->getHandlerBlock());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToCatchLoc;
- VarDecl *ToExceptionDecl;
- Stmt *ToHandlerBlock;
- std::tie(ToCatchLoc, ToExceptionDecl, ToHandlerBlock) = *Imp;
- return new (Importer.getToContext()) CXXCatchStmt (
- ToCatchLoc, ToExceptionDecl, ToHandlerBlock);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
- ExpectedSLoc ToTryLocOrErr = import(S->getTryLoc());
- if (!ToTryLocOrErr)
- return ToTryLocOrErr.takeError();
- ExpectedStmt ToTryBlockOrErr = import(S->getTryBlock());
- if (!ToTryBlockOrErr)
- return ToTryBlockOrErr.takeError();
- SmallVector<Stmt *, 1> ToHandlers(S->getNumHandlers());
- for (unsigned HI = 0, HE = S->getNumHandlers(); HI != HE; ++HI) {
- CXXCatchStmt *FromHandler = S->getHandler(HI);
- if (auto ToHandlerOrErr = import(FromHandler))
- ToHandlers[HI] = *ToHandlerOrErr;
- else
- return ToHandlerOrErr.takeError();
- }
- return CXXTryStmt::Create(
- Importer.getToContext(), *ToTryLocOrErr,*ToTryBlockOrErr, ToHandlers);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
- auto Imp1 = importSeq(
- S->getInit(), S->getRangeStmt(), S->getBeginStmt(), S->getEndStmt(),
- S->getCond(), S->getInc(), S->getLoopVarStmt(), S->getBody());
- if (!Imp1)
- return Imp1.takeError();
- auto Imp2 = importSeq(
- S->getForLoc(), S->getCoawaitLoc(), S->getColonLoc(), S->getRParenLoc());
- if (!Imp2)
- return Imp2.takeError();
- DeclStmt *ToRangeStmt, *ToBeginStmt, *ToEndStmt, *ToLoopVarStmt;
- Expr *ToCond, *ToInc;
- Stmt *ToInit, *ToBody;
- std::tie(
- ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
- ToBody) = *Imp1;
- SourceLocation ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc;
- std::tie(ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc) = *Imp2;
- return new (Importer.getToContext()) CXXForRangeStmt(
- ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
- ToBody, ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
- auto Imp = importSeq(
- S->getElement(), S->getCollection(), S->getBody(),
- S->getForLoc(), S->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- Stmt *ToElement, *ToBody;
- Expr *ToCollection;
- SourceLocation ToForLoc, ToRParenLoc;
- std::tie(ToElement, ToCollection, ToBody, ToForLoc, ToRParenLoc) = *Imp;
- return new (Importer.getToContext()) ObjCForCollectionStmt(ToElement,
- ToCollection,
- ToBody,
- ToForLoc,
- ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
- auto Imp = importSeq(
- S->getAtCatchLoc(), S->getRParenLoc(), S->getCatchParamDecl(),
- S->getCatchBody());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToAtCatchLoc, ToRParenLoc;
- VarDecl *ToCatchParamDecl;
- Stmt *ToCatchBody;
- std::tie(ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody) = *Imp;
- return new (Importer.getToContext()) ObjCAtCatchStmt (
- ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
- ExpectedSLoc ToAtFinallyLocOrErr = import(S->getAtFinallyLoc());
- if (!ToAtFinallyLocOrErr)
- return ToAtFinallyLocOrErr.takeError();
- ExpectedStmt ToAtFinallyStmtOrErr = import(S->getFinallyBody());
- if (!ToAtFinallyStmtOrErr)
- return ToAtFinallyStmtOrErr.takeError();
- return new (Importer.getToContext()) ObjCAtFinallyStmt(*ToAtFinallyLocOrErr,
- *ToAtFinallyStmtOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
- auto Imp = importSeq(
- S->getAtTryLoc(), S->getTryBody(), S->getFinallyStmt());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToAtTryLoc;
- Stmt *ToTryBody, *ToFinallyStmt;
- std::tie(ToAtTryLoc, ToTryBody, ToFinallyStmt) = *Imp;
- SmallVector<Stmt *, 1> ToCatchStmts(S->getNumCatchStmts());
- for (unsigned CI = 0, CE = S->getNumCatchStmts(); CI != CE; ++CI) {
- ObjCAtCatchStmt *FromCatchStmt = S->getCatchStmt(CI);
- if (ExpectedStmt ToCatchStmtOrErr = import(FromCatchStmt))
- ToCatchStmts[CI] = *ToCatchStmtOrErr;
- else
- return ToCatchStmtOrErr.takeError();
- }
- return ObjCAtTryStmt::Create(Importer.getToContext(),
- ToAtTryLoc, ToTryBody,
- ToCatchStmts.begin(), ToCatchStmts.size(),
- ToFinallyStmt);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtSynchronizedStmt
- (ObjCAtSynchronizedStmt *S) {
- auto Imp = importSeq(
- S->getAtSynchronizedLoc(), S->getSynchExpr(), S->getSynchBody());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToAtSynchronizedLoc;
- Expr *ToSynchExpr;
- Stmt *ToSynchBody;
- std::tie(ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody) = *Imp;
- return new (Importer.getToContext()) ObjCAtSynchronizedStmt(
- ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- ExpectedSLoc ToThrowLocOrErr = import(S->getThrowLoc());
- if (!ToThrowLocOrErr)
- return ToThrowLocOrErr.takeError();
- ExpectedExpr ToThrowExprOrErr = import(S->getThrowExpr());
- if (!ToThrowExprOrErr)
- return ToThrowExprOrErr.takeError();
- return new (Importer.getToContext()) ObjCAtThrowStmt(
- *ToThrowLocOrErr, *ToThrowExprOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAutoreleasePoolStmt(
- ObjCAutoreleasePoolStmt *S) {
- ExpectedSLoc ToAtLocOrErr = import(S->getAtLoc());
- if (!ToAtLocOrErr)
- return ToAtLocOrErr.takeError();
- ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
- if (!ToSubStmtOrErr)
- return ToSubStmtOrErr.takeError();
- return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(*ToAtLocOrErr,
- *ToSubStmtOrErr);
- }
- //----------------------------------------------------------------------------
- // Import Expressions
- //----------------------------------------------------------------------------
- ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
- Importer.FromDiag(E->getBeginLoc(), diag::err_unsupported_ast_node)
- << E->getStmtClassName();
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
- auto Imp = importSeq(
- E->getBuiltinLoc(), E->getSubExpr(), E->getWrittenTypeInfo(),
- E->getRParenLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToBuiltinLoc, ToRParenLoc;
- Expr *ToSubExpr;
- TypeSourceInfo *ToWrittenTypeInfo;
- QualType ToType;
- std::tie(ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType) =
- *Imp;
- return new (Importer.getToContext()) VAArgExpr(
- ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType,
- E->isMicrosoftABI());
- }
- ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) {
- auto Imp = importSeq(E->getCond(), E->getLHS(), E->getRHS(),
- E->getBuiltinLoc(), E->getRParenLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- Expr *ToCond;
- Expr *ToLHS;
- Expr *ToRHS;
- SourceLocation ToBuiltinLoc, ToRParenLoc;
- QualType ToType;
- std::tie(ToCond, ToLHS, ToRHS, ToBuiltinLoc, ToRParenLoc, ToType) = *Imp;
- ExprValueKind VK = E->getValueKind();
- ExprObjectKind OK = E->getObjectKind();
- bool TypeDependent = ToCond->isTypeDependent();
- bool ValueDependent = ToCond->isValueDependent();
- // The value of CondIsTrue only matters if the value is not
- // condition-dependent.
- bool CondIsTrue = !E->isConditionDependent() && E->isConditionTrue();
- return new (Importer.getToContext())
- ChooseExpr(ToBuiltinLoc, ToCond, ToLHS, ToRHS, ToType, VK, OK,
- ToRParenLoc, CondIsTrue, TypeDependent, ValueDependent);
- }
- ExpectedStmt ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
- ExpectedType TypeOrErr = import(E->getType());
- if (!TypeOrErr)
- return TypeOrErr.takeError();
- ExpectedSLoc BeginLocOrErr = import(E->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- return new (Importer.getToContext()) GNUNullExpr(*TypeOrErr, *BeginLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
- auto Imp = importSeq(
- E->getBeginLoc(), E->getType(), E->getFunctionName());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToBeginLoc;
- QualType ToType;
- StringLiteral *ToFunctionName;
- std::tie(ToBeginLoc, ToType, ToFunctionName) = *Imp;
- return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType,
- E->getIdentKind(), ToFunctionName);
- }
- ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
- auto Imp = importSeq(
- E->getQualifierLoc(), E->getTemplateKeywordLoc(), E->getDecl(),
- E->getLocation(), E->getType());
- if (!Imp)
- return Imp.takeError();
- NestedNameSpecifierLoc ToQualifierLoc;
- SourceLocation ToTemplateKeywordLoc, ToLocation;
- ValueDecl *ToDecl;
- QualType ToType;
- std::tie(ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, ToLocation, ToType) =
- *Imp;
- NamedDecl *ToFoundD = nullptr;
- if (E->getDecl() != E->getFoundDecl()) {
- auto FoundDOrErr = import(E->getFoundDecl());
- if (!FoundDOrErr)
- return FoundDOrErr.takeError();
- ToFoundD = *FoundDOrErr;
- }
- TemplateArgumentListInfo ToTAInfo;
- TemplateArgumentListInfo *ToResInfo = nullptr;
- if (E->hasExplicitTemplateArgs()) {
- if (Error Err =
- ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
- return std::move(Err);
- ToResInfo = &ToTAInfo;
- }
- auto *ToE = DeclRefExpr::Create(
- Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl,
- E->refersToEnclosingVariableOrCapture(), ToLocation, ToType,
- E->getValueKind(), ToFoundD, ToResInfo);
- if (E->hadMultipleCandidates())
- ToE->setHadMultipleCandidates(true);
- return ToE;
- }
- ExpectedStmt ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
- ExpectedType TypeOrErr = import(E->getType());
- if (!TypeOrErr)
- return TypeOrErr.takeError();
- return new (Importer.getToContext()) ImplicitValueInitExpr(*TypeOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
- ExpectedExpr ToInitOrErr = import(E->getInit());
- if (!ToInitOrErr)
- return ToInitOrErr.takeError();
- ExpectedSLoc ToEqualOrColonLocOrErr = import(E->getEqualOrColonLoc());
- if (!ToEqualOrColonLocOrErr)
- return ToEqualOrColonLocOrErr.takeError();
- SmallVector<Expr *, 4> ToIndexExprs(E->getNumSubExprs() - 1);
- // List elements from the second, the first is Init itself
- for (unsigned I = 1, N = E->getNumSubExprs(); I < N; I++) {
- if (ExpectedExpr ToArgOrErr = import(E->getSubExpr(I)))
- ToIndexExprs[I - 1] = *ToArgOrErr;
- else
- return ToArgOrErr.takeError();
- }
- SmallVector<Designator, 4> ToDesignators(E->size());
- if (Error Err = ImportContainerChecked(E->designators(), ToDesignators))
- return std::move(Err);
- return DesignatedInitExpr::Create(
- Importer.getToContext(), ToDesignators,
- ToIndexExprs, *ToEqualOrColonLocOrErr,
- E->usesGNUSyntax(), *ToInitOrErr);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return new (Importer.getToContext()) CXXNullPtrLiteralExpr(
- *ToTypeOrErr, *ToLocationOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return IntegerLiteral::Create(
- Importer.getToContext(), E->getValue(), *ToTypeOrErr, *ToLocationOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return FloatingLiteral::Create(
- Importer.getToContext(), E->getValue(), E->isExact(),
- *ToTypeOrErr, *ToLocationOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
- auto ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
- if (!ToSubExprOrErr)
- return ToSubExprOrErr.takeError();
- return new (Importer.getToContext()) ImaginaryLiteral(
- *ToSubExprOrErr, *ToTypeOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return new (Importer.getToContext()) CharacterLiteral(
- E->getValue(), E->getKind(), *ToTypeOrErr, *ToLocationOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitStringLiteral(StringLiteral *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- SmallVector<SourceLocation, 4> ToLocations(E->getNumConcatenated());
- if (Error Err = ImportArrayChecked(
- E->tokloc_begin(), E->tokloc_end(), ToLocations.begin()))
- return std::move(Err);
- return StringLiteral::Create(
- Importer.getToContext(), E->getBytes(), E->getKind(), E->isPascal(),
- *ToTypeOrErr, ToLocations.data(), ToLocations.size());
- }
- ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
- auto Imp = importSeq(
- E->getLParenLoc(), E->getTypeSourceInfo(), E->getType(),
- E->getInitializer());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLParenLoc;
- TypeSourceInfo *ToTypeSourceInfo;
- QualType ToType;
- Expr *ToInitializer;
- std::tie(ToLParenLoc, ToTypeSourceInfo, ToType, ToInitializer) = *Imp;
- return new (Importer.getToContext()) CompoundLiteralExpr(
- ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(),
- ToInitializer, E->isFileScope());
- }
- ExpectedStmt ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
- auto Imp = importSeq(
- E->getBuiltinLoc(), E->getType(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToBuiltinLoc, ToRParenLoc;
- QualType ToType;
- std::tie(ToBuiltinLoc, ToType, ToRParenLoc) = *Imp;
- SmallVector<Expr *, 6> ToExprs(E->getNumSubExprs());
- if (Error Err = ImportArrayChecked(
- E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(),
- ToExprs.begin()))
- return std::move(Err);
- return new (Importer.getToContext()) AtomicExpr(
- ToBuiltinLoc, ToExprs, ToType, E->getOp(), ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) {
- auto Imp = importSeq(
- E->getAmpAmpLoc(), E->getLabelLoc(), E->getLabel(), E->getType());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToAmpAmpLoc, ToLabelLoc;
- LabelDecl *ToLabel;
- QualType ToType;
- std::tie(ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType) = *Imp;
- return new (Importer.getToContext()) AddrLabelExpr(
- ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
- auto Imp = importSeq(E->getSubExpr());
- if (!Imp)
- return Imp.takeError();
- Expr *ToSubExpr;
- std::tie(ToSubExpr) = *Imp;
- return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
- }
- ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
- auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLParen, ToRParen;
- Expr *ToSubExpr;
- std::tie(ToLParen, ToRParen, ToSubExpr) = *Imp;
- return new (Importer.getToContext())
- ParenExpr(ToLParen, ToRParen, ToSubExpr);
- }
- ExpectedStmt ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
- SmallVector<Expr *, 4> ToExprs(E->getNumExprs());
- if (Error Err = ImportContainerChecked(E->exprs(), ToExprs))
- return std::move(Err);
- ExpectedSLoc ToLParenLocOrErr = import(E->getLParenLoc());
- if (!ToLParenLocOrErr)
- return ToLParenLocOrErr.takeError();
- ExpectedSLoc ToRParenLocOrErr = import(E->getRParenLoc());
- if (!ToRParenLocOrErr)
- return ToRParenLocOrErr.takeError();
- return ParenListExpr::Create(Importer.getToContext(), *ToLParenLocOrErr,
- ToExprs, *ToRParenLocOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
- auto Imp = importSeq(
- E->getSubStmt(), E->getType(), E->getLParenLoc(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- CompoundStmt *ToSubStmt;
- QualType ToType;
- SourceLocation ToLParenLoc, ToRParenLoc;
- std::tie(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc) = *Imp;
- return new (Importer.getToContext()) StmtExpr(
- ToSubStmt, ToType, ToLParenLoc, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
- auto Imp = importSeq(
- E->getSubExpr(), E->getType(), E->getOperatorLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToSubExpr;
- QualType ToType;
- SourceLocation ToOperatorLoc;
- std::tie(ToSubExpr, ToType, ToOperatorLoc) = *Imp;
- return new (Importer.getToContext()) UnaryOperator(
- ToSubExpr, E->getOpcode(), ToType, E->getValueKind(), E->getObjectKind(),
- ToOperatorLoc, E->canOverflow());
- }
- ExpectedStmt
- ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
- auto Imp = importSeq(E->getType(), E->getOperatorLoc(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- SourceLocation ToOperatorLoc, ToRParenLoc;
- std::tie(ToType, ToOperatorLoc, ToRParenLoc) = *Imp;
- if (E->isArgumentType()) {
- Expected<TypeSourceInfo *> ToArgumentTypeInfoOrErr =
- import(E->getArgumentTypeInfo());
- if (!ToArgumentTypeInfoOrErr)
- return ToArgumentTypeInfoOrErr.takeError();
- return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
- E->getKind(), *ToArgumentTypeInfoOrErr, ToType, ToOperatorLoc,
- ToRParenLoc);
- }
- ExpectedExpr ToArgumentExprOrErr = import(E->getArgumentExpr());
- if (!ToArgumentExprOrErr)
- return ToArgumentExprOrErr.takeError();
- return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
- E->getKind(), *ToArgumentExprOrErr, ToType, ToOperatorLoc, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
- auto Imp = importSeq(
- E->getLHS(), E->getRHS(), E->getType(), E->getOperatorLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToLHS, *ToRHS;
- QualType ToType;
- SourceLocation ToOperatorLoc;
- std::tie(ToLHS, ToRHS, ToType, ToOperatorLoc) = *Imp;
- return new (Importer.getToContext()) BinaryOperator(
- ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
- E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
- }
- ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
- auto Imp = importSeq(
- E->getCond(), E->getQuestionLoc(), E->getLHS(), E->getColonLoc(),
- E->getRHS(), E->getType());
- if (!Imp)
- return Imp.takeError();
- Expr *ToCond, *ToLHS, *ToRHS;
- SourceLocation ToQuestionLoc, ToColonLoc;
- QualType ToType;
- std::tie(ToCond, ToQuestionLoc, ToLHS, ToColonLoc, ToRHS, ToType) = *Imp;
- return new (Importer.getToContext()) ConditionalOperator(
- ToCond, ToQuestionLoc, ToLHS, ToColonLoc, ToRHS, ToType,
- E->getValueKind(), E->getObjectKind());
- }
- ExpectedStmt ASTNodeImporter::VisitBinaryConditionalOperator(
- BinaryConditionalOperator *E) {
- auto Imp = importSeq(
- E->getCommon(), E->getOpaqueValue(), E->getCond(), E->getTrueExpr(),
- E->getFalseExpr(), E->getQuestionLoc(), E->getColonLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- Expr *ToCommon, *ToCond, *ToTrueExpr, *ToFalseExpr;
- OpaqueValueExpr *ToOpaqueValue;
- SourceLocation ToQuestionLoc, ToColonLoc;
- QualType ToType;
- std::tie(
- ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr, ToQuestionLoc,
- ToColonLoc, ToType) = *Imp;
- return new (Importer.getToContext()) BinaryConditionalOperator(
- ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr,
- ToQuestionLoc, ToColonLoc, ToType, E->getValueKind(),
- E->getObjectKind());
- }
- ExpectedStmt ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
- auto Imp = importSeq(
- E->getBeginLoc(), E->getQueriedTypeSourceInfo(),
- E->getDimensionExpression(), E->getEndLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToBeginLoc, ToEndLoc;
- TypeSourceInfo *ToQueriedTypeSourceInfo;
- Expr *ToDimensionExpression;
- QualType ToType;
- std::tie(
- ToBeginLoc, ToQueriedTypeSourceInfo, ToDimensionExpression, ToEndLoc,
- ToType) = *Imp;
- return new (Importer.getToContext()) ArrayTypeTraitExpr(
- ToBeginLoc, E->getTrait(), ToQueriedTypeSourceInfo, E->getValue(),
- ToDimensionExpression, ToEndLoc, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
- auto Imp = importSeq(
- E->getBeginLoc(), E->getQueriedExpression(), E->getEndLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToBeginLoc, ToEndLoc;
- Expr *ToQueriedExpression;
- QualType ToType;
- std::tie(ToBeginLoc, ToQueriedExpression, ToEndLoc, ToType) = *Imp;
- return new (Importer.getToContext()) ExpressionTraitExpr(
- ToBeginLoc, E->getTrait(), ToQueriedExpression, E->getValue(),
- ToEndLoc, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
- auto Imp = importSeq(
- E->getLocation(), E->getType(), E->getSourceExpr());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLocation;
- QualType ToType;
- Expr *ToSourceExpr;
- std::tie(ToLocation, ToType, ToSourceExpr) = *Imp;
- return new (Importer.getToContext()) OpaqueValueExpr(
- ToLocation, ToType, E->getValueKind(), E->getObjectKind(), ToSourceExpr);
- }
- ExpectedStmt ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- auto Imp = importSeq(
- E->getLHS(), E->getRHS(), E->getType(), E->getRBracketLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToLHS, *ToRHS;
- SourceLocation ToRBracketLoc;
- QualType ToType;
- std::tie(ToLHS, ToRHS, ToType, ToRBracketLoc) = *Imp;
- return new (Importer.getToContext()) ArraySubscriptExpr(
- ToLHS, ToRHS, ToType, E->getValueKind(), E->getObjectKind(),
- ToRBracketLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- auto Imp = importSeq(
- E->getLHS(), E->getRHS(), E->getType(), E->getComputationLHSType(),
- E->getComputationResultType(), E->getOperatorLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToLHS, *ToRHS;
- QualType ToType, ToComputationLHSType, ToComputationResultType;
- SourceLocation ToOperatorLoc;
- std::tie(ToLHS, ToRHS, ToType, ToComputationLHSType, ToComputationResultType,
- ToOperatorLoc) = *Imp;
- return new (Importer.getToContext()) CompoundAssignOperator(
- ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
- E->getObjectKind(), ToComputationLHSType, ToComputationResultType,
- ToOperatorLoc, E->getFPFeatures());
- }
- Expected<CXXCastPath>
- ASTNodeImporter::ImportCastPath(CastExpr *CE) {
- CXXCastPath Path;
- for (auto I = CE->path_begin(), E = CE->path_end(); I != E; ++I) {
- if (auto SpecOrErr = import(*I))
- Path.push_back(*SpecOrErr);
- else
- return SpecOrErr.takeError();
- }
- return Path;
- }
- ExpectedStmt ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
- if (!ToSubExprOrErr)
- return ToSubExprOrErr.takeError();
- Expected<CXXCastPath> ToBasePathOrErr = ImportCastPath(E);
- if (!ToBasePathOrErr)
- return ToBasePathOrErr.takeError();
- return ImplicitCastExpr::Create(
- Importer.getToContext(), *ToTypeOrErr, E->getCastKind(), *ToSubExprOrErr,
- &(*ToBasePathOrErr), E->getValueKind());
- }
- ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
- auto Imp1 = importSeq(
- E->getType(), E->getSubExpr(), E->getTypeInfoAsWritten());
- if (!Imp1)
- return Imp1.takeError();
- QualType ToType;
- Expr *ToSubExpr;
- TypeSourceInfo *ToTypeInfoAsWritten;
- std::tie(ToType, ToSubExpr, ToTypeInfoAsWritten) = *Imp1;
- Expected<CXXCastPath> ToBasePathOrErr = ImportCastPath(E);
- if (!ToBasePathOrErr)
- return ToBasePathOrErr.takeError();
- CXXCastPath *ToBasePath = &(*ToBasePathOrErr);
- switch (E->getStmtClass()) {
- case Stmt::CStyleCastExprClass: {
- auto *CCE = cast<CStyleCastExpr>(E);
- ExpectedSLoc ToLParenLocOrErr = import(CCE->getLParenLoc());
- if (!ToLParenLocOrErr)
- return ToLParenLocOrErr.takeError();
- ExpectedSLoc ToRParenLocOrErr = import(CCE->getRParenLoc());
- if (!ToRParenLocOrErr)
- return ToRParenLocOrErr.takeError();
- return CStyleCastExpr::Create(
- Importer.getToContext(), ToType, E->getValueKind(), E->getCastKind(),
- ToSubExpr, ToBasePath, ToTypeInfoAsWritten, *ToLParenLocOrErr,
- *ToRParenLocOrErr);
- }
- case Stmt::CXXFunctionalCastExprClass: {
- auto *FCE = cast<CXXFunctionalCastExpr>(E);
- ExpectedSLoc ToLParenLocOrErr = import(FCE->getLParenLoc());
- if (!ToLParenLocOrErr)
- return ToLParenLocOrErr.takeError();
- ExpectedSLoc ToRParenLocOrErr = import(FCE->getRParenLoc());
- if (!ToRParenLocOrErr)
- return ToRParenLocOrErr.takeError();
- return CXXFunctionalCastExpr::Create(
- Importer.getToContext(), ToType, E->getValueKind(), ToTypeInfoAsWritten,
- E->getCastKind(), ToSubExpr, ToBasePath, *ToLParenLocOrErr,
- *ToRParenLocOrErr);
- }
- case Stmt::ObjCBridgedCastExprClass: {
- auto *OCE = cast<ObjCBridgedCastExpr>(E);
- ExpectedSLoc ToLParenLocOrErr = import(OCE->getLParenLoc());
- if (!ToLParenLocOrErr)
- return ToLParenLocOrErr.takeError();
- ExpectedSLoc ToBridgeKeywordLocOrErr = import(OCE->getBridgeKeywordLoc());
- if (!ToBridgeKeywordLocOrErr)
- return ToBridgeKeywordLocOrErr.takeError();
- return new (Importer.getToContext()) ObjCBridgedCastExpr(
- *ToLParenLocOrErr, OCE->getBridgeKind(), E->getCastKind(),
- *ToBridgeKeywordLocOrErr, ToTypeInfoAsWritten, ToSubExpr);
- }
- default:
- llvm_unreachable("Cast expression of unsupported type!");
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- }
- ExpectedStmt ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *E) {
- SmallVector<OffsetOfNode, 4> ToNodes;
- for (int I = 0, N = E->getNumComponents(); I < N; ++I) {
- const OffsetOfNode &FromNode = E->getComponent(I);
- SourceLocation ToBeginLoc, ToEndLoc;
- if (FromNode.getKind() != OffsetOfNode::Base) {
- auto Imp = importSeq(FromNode.getBeginLoc(), FromNode.getEndLoc());
- if (!Imp)
- return Imp.takeError();
- std::tie(ToBeginLoc, ToEndLoc) = *Imp;
- }
- switch (FromNode.getKind()) {
- case OffsetOfNode::Array:
- ToNodes.push_back(
- OffsetOfNode(ToBeginLoc, FromNode.getArrayExprIndex(), ToEndLoc));
- break;
- case OffsetOfNode::Base: {
- auto ToBSOrErr = import(FromNode.getBase());
- if (!ToBSOrErr)
- return ToBSOrErr.takeError();
- ToNodes.push_back(OffsetOfNode(*ToBSOrErr));
- break;
- }
- case OffsetOfNode::Field: {
- auto ToFieldOrErr = import(FromNode.getField());
- if (!ToFieldOrErr)
- return ToFieldOrErr.takeError();
- ToNodes.push_back(OffsetOfNode(ToBeginLoc, *ToFieldOrErr, ToEndLoc));
- break;
- }
- case OffsetOfNode::Identifier: {
- IdentifierInfo *ToII = Importer.Import(FromNode.getFieldName());
- ToNodes.push_back(OffsetOfNode(ToBeginLoc, ToII, ToEndLoc));
- break;
- }
- }
- }
- SmallVector<Expr *, 4> ToExprs(E->getNumExpressions());
- for (int I = 0, N = E->getNumExpressions(); I < N; ++I) {
- ExpectedExpr ToIndexExprOrErr = import(E->getIndexExpr(I));
- if (!ToIndexExprOrErr)
- return ToIndexExprOrErr.takeError();
- ToExprs[I] = *ToIndexExprOrErr;
- }
- auto Imp = importSeq(
- E->getType(), E->getTypeSourceInfo(), E->getOperatorLoc(),
- E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceLocation ToOperatorLoc, ToRParenLoc;
- std::tie(ToType, ToTypeSourceInfo, ToOperatorLoc, ToRParenLoc) = *Imp;
- return OffsetOfExpr::Create(
- Importer.getToContext(), ToType, ToOperatorLoc, ToTypeSourceInfo, ToNodes,
- ToExprs, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getOperand(), E->getBeginLoc(), E->getEndLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- Expr *ToOperand;
- SourceLocation ToBeginLoc, ToEndLoc;
- std::tie(ToType, ToOperand, ToBeginLoc, ToEndLoc) = *Imp;
- CanThrowResult ToCanThrow;
- if (E->isValueDependent())
- ToCanThrow = CT_Dependent;
- else
- ToCanThrow = E->getValue() ? CT_Can : CT_Cannot;
- return new (Importer.getToContext()) CXXNoexceptExpr(
- ToType, ToOperand, ToCanThrow, ToBeginLoc, ToEndLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) {
- auto Imp = importSeq(E->getSubExpr(), E->getType(), E->getThrowLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToSubExpr;
- QualType ToType;
- SourceLocation ToThrowLoc;
- std::tie(ToSubExpr, ToType, ToThrowLoc) = *Imp;
- return new (Importer.getToContext()) CXXThrowExpr(
- ToSubExpr, ToType, ToThrowLoc, E->isThrownVariableInScope());
- }
- ExpectedStmt ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- ExpectedSLoc ToUsedLocOrErr = import(E->getUsedLocation());
- if (!ToUsedLocOrErr)
- return ToUsedLocOrErr.takeError();
- auto ToParamOrErr = import(E->getParam());
- if (!ToParamOrErr)
- return ToParamOrErr.takeError();
- auto UsedContextOrErr = Importer.ImportContext(E->getUsedContext());
- if (!UsedContextOrErr)
- return UsedContextOrErr.takeError();
- return CXXDefaultArgExpr::Create(
- Importer.getToContext(), *ToUsedLocOrErr, *ToParamOrErr, *UsedContextOrErr);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getTypeSourceInfo(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceLocation ToRParenLoc;
- std::tie(ToType, ToTypeSourceInfo, ToRParenLoc) = *Imp;
- return new (Importer.getToContext()) CXXScalarValueInitExpr(
- ToType, ToTypeSourceInfo, ToRParenLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
- if (!ToSubExprOrErr)
- return ToSubExprOrErr.takeError();
- auto ToDtorOrErr = import(E->getTemporary()->getDestructor());
- if (!ToDtorOrErr)
- return ToDtorOrErr.takeError();
- ASTContext &ToCtx = Importer.getToContext();
- CXXTemporary *Temp = CXXTemporary::Create(ToCtx, *ToDtorOrErr);
- return CXXBindTemporaryExpr::Create(ToCtx, Temp, *ToSubExprOrErr);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
- auto Imp = importSeq(
- E->getConstructor(), E->getType(), E->getTypeSourceInfo(),
- E->getParenOrBraceRange());
- if (!Imp)
- return Imp.takeError();
- CXXConstructorDecl *ToConstructor;
- QualType ToType;
- TypeSourceInfo *ToTypeSourceInfo;
- SourceRange ToParenOrBraceRange;
- std::tie(ToConstructor, ToType, ToTypeSourceInfo, ToParenOrBraceRange) = *Imp;
- SmallVector<Expr *, 8> ToArgs(E->getNumArgs());
- if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
- return std::move(Err);
- return CXXTemporaryObjectExpr::Create(
- Importer.getToContext(), ToConstructor, ToType, ToTypeSourceInfo, ToArgs,
- ToParenOrBraceRange, E->hadMultipleCandidates(),
- E->isListInitialization(), E->isStdInitListInitialization(),
- E->requiresZeroInitialization());
- }
- ExpectedStmt
- ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->GetTemporaryExpr(), E->getExtendingDecl());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- Expr *ToTemporaryExpr;
- const ValueDecl *ToExtendingDecl;
- std::tie(ToType, ToTemporaryExpr, ToExtendingDecl) = *Imp;
- auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr(
- ToType, ToTemporaryExpr, E->isBoundToLvalueReference());
- // FIXME: Should ManglingNumber get numbers associated with 'to' context?
- ToMTE->setExtendingDecl(ToExtendingDecl, E->getManglingNumber());
- return ToMTE;
- }
- ExpectedStmt ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getPattern(), E->getEllipsisLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- Expr *ToPattern;
- SourceLocation ToEllipsisLoc;
- std::tie(ToType, ToPattern, ToEllipsisLoc) = *Imp;
- return new (Importer.getToContext()) PackExpansionExpr(
- ToType, ToPattern, ToEllipsisLoc, E->getNumExpansions());
- }
- ExpectedStmt ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
- auto Imp = importSeq(
- E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToOperatorLoc, ToPackLoc, ToRParenLoc;
- NamedDecl *ToPack;
- std::tie(ToOperatorLoc, ToPack, ToPackLoc, ToRParenLoc) = *Imp;
- Optional<unsigned> Length;
- if (!E->isValueDependent())
- Length = E->getPackLength();
- SmallVector<TemplateArgument, 8> ToPartialArguments;
- if (E->isPartiallySubstituted()) {
- if (Error Err = ImportTemplateArguments(
- E->getPartialArguments().data(),
- E->getPartialArguments().size(),
- ToPartialArguments))
- return std::move(Err);
- }
- return SizeOfPackExpr::Create(
- Importer.getToContext(), ToOperatorLoc, ToPack, ToPackLoc, ToRParenLoc,
- Length, ToPartialArguments);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) {
- auto Imp = importSeq(
- E->getOperatorNew(), E->getOperatorDelete(), E->getTypeIdParens(),
- E->getArraySize(), E->getInitializer(), E->getType(),
- E->getAllocatedTypeSourceInfo(), E->getSourceRange(),
- E->getDirectInitRange());
- if (!Imp)
- return Imp.takeError();
- FunctionDecl *ToOperatorNew, *ToOperatorDelete;
- SourceRange ToTypeIdParens, ToSourceRange, ToDirectInitRange;
- Optional<Expr *> ToArraySize;
- Expr *ToInitializer;
- QualType ToType;
- TypeSourceInfo *ToAllocatedTypeSourceInfo;
- std::tie(
- ToOperatorNew, ToOperatorDelete, ToTypeIdParens, ToArraySize, ToInitializer,
- ToType, ToAllocatedTypeSourceInfo, ToSourceRange, ToDirectInitRange) = *Imp;
- SmallVector<Expr *, 4> ToPlacementArgs(E->getNumPlacementArgs());
- if (Error Err =
- ImportContainerChecked(E->placement_arguments(), ToPlacementArgs))
- return std::move(Err);
- return CXXNewExpr::Create(
- Importer.getToContext(), E->isGlobalNew(), ToOperatorNew,
- ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(),
- ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(),
- ToInitializer, ToType, ToAllocatedTypeSourceInfo, ToSourceRange,
- ToDirectInitRange);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getOperatorDelete(), E->getArgument(), E->getBeginLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- FunctionDecl *ToOperatorDelete;
- Expr *ToArgument;
- SourceLocation ToBeginLoc;
- std::tie(ToType, ToOperatorDelete, ToArgument, ToBeginLoc) = *Imp;
- return new (Importer.getToContext()) CXXDeleteExpr(
- ToType, E->isGlobalDelete(), E->isArrayForm(), E->isArrayFormAsWritten(),
- E->doesUsualArrayDeleteWantSize(), ToOperatorDelete, ToArgument,
- ToBeginLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getLocation(), E->getConstructor(),
- E->getParenOrBraceRange());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- SourceLocation ToLocation;
- CXXConstructorDecl *ToConstructor;
- SourceRange ToParenOrBraceRange;
- std::tie(ToType, ToLocation, ToConstructor, ToParenOrBraceRange) = *Imp;
- SmallVector<Expr *, 6> ToArgs(E->getNumArgs());
- if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
- return std::move(Err);
- return CXXConstructExpr::Create(
- Importer.getToContext(), ToType, ToLocation, ToConstructor,
- E->isElidable(), ToArgs, E->hadMultipleCandidates(),
- E->isListInitialization(), E->isStdInitListInitialization(),
- E->requiresZeroInitialization(), E->getConstructionKind(),
- ToParenOrBraceRange);
- }
- ExpectedStmt ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *E) {
- ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
- if (!ToSubExprOrErr)
- return ToSubExprOrErr.takeError();
- SmallVector<ExprWithCleanups::CleanupObject, 8> ToObjects(E->getNumObjects());
- if (Error Err = ImportContainerChecked(E->getObjects(), ToObjects))
- return std::move(Err);
- return ExprWithCleanups::Create(
- Importer.getToContext(), *ToSubExprOrErr, E->cleanupsHaveSideEffects(),
- ToObjects);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
- auto Imp = importSeq(
- E->getCallee(), E->getType(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToCallee;
- QualType ToType;
- SourceLocation ToRParenLoc;
- std::tie(ToCallee, ToType, ToRParenLoc) = *Imp;
- SmallVector<Expr *, 4> ToArgs(E->getNumArgs());
- if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
- return std::move(Err);
- return CXXMemberCallExpr::Create(Importer.getToContext(), ToCallee, ToArgs,
- ToType, E->getValueKind(), ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return new (Importer.getToContext()) CXXThisExpr(
- *ToLocationOrErr, *ToTypeOrErr, E->isImplicit());
- }
- ExpectedStmt ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return new (Importer.getToContext()) CXXBoolLiteralExpr(
- E->getValue(), *ToTypeOrErr, *ToLocationOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
- auto Imp1 = importSeq(
- E->getBase(), E->getOperatorLoc(), E->getQualifierLoc(),
- E->getTemplateKeywordLoc(), E->getMemberDecl(), E->getType());
- if (!Imp1)
- return Imp1.takeError();
- Expr *ToBase;
- SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- ValueDecl *ToMemberDecl;
- QualType ToType;
- std::tie(
- ToBase, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl,
- ToType) = *Imp1;
- auto Imp2 = importSeq(
- E->getFoundDecl().getDecl(), E->getMemberNameInfo().getName(),
- E->getMemberNameInfo().getLoc(), E->getLAngleLoc(), E->getRAngleLoc());
- if (!Imp2)
- return Imp2.takeError();
- NamedDecl *ToDecl;
- DeclarationName ToName;
- SourceLocation ToLoc, ToLAngleLoc, ToRAngleLoc;
- std::tie(ToDecl, ToName, ToLoc, ToLAngleLoc, ToRAngleLoc) = *Imp2;
- DeclAccessPair ToFoundDecl =
- DeclAccessPair::make(ToDecl, E->getFoundDecl().getAccess());
- DeclarationNameInfo ToMemberNameInfo(ToName, ToLoc);
- TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
- if (E->hasExplicitTemplateArgs()) {
- if (Error Err =
- ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
- E->template_arguments(), ToTAInfo))
- return std::move(Err);
- ResInfo = &ToTAInfo;
- }
- return MemberExpr::Create(
- Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
- ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
- ToMemberNameInfo, ResInfo, ToType, E->getValueKind(), E->getObjectKind());
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
- auto Imp = importSeq(
- E->getBase(), E->getOperatorLoc(), E->getQualifierLoc(),
- E->getScopeTypeInfo(), E->getColonColonLoc(), E->getTildeLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToBase;
- SourceLocation ToOperatorLoc, ToColonColonLoc, ToTildeLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- TypeSourceInfo *ToScopeTypeInfo;
- std::tie(
- ToBase, ToOperatorLoc, ToQualifierLoc, ToScopeTypeInfo, ToColonColonLoc,
- ToTildeLoc) = *Imp;
- PseudoDestructorTypeStorage Storage;
- if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) {
- IdentifierInfo *ToII = Importer.Import(FromII);
- ExpectedSLoc ToDestroyedTypeLocOrErr = import(E->getDestroyedTypeLoc());
- if (!ToDestroyedTypeLocOrErr)
- return ToDestroyedTypeLocOrErr.takeError();
- Storage = PseudoDestructorTypeStorage(ToII, *ToDestroyedTypeLocOrErr);
- } else {
- if (auto ToTIOrErr = import(E->getDestroyedTypeInfo()))
- Storage = PseudoDestructorTypeStorage(*ToTIOrErr);
- else
- return ToTIOrErr.takeError();
- }
- return new (Importer.getToContext()) CXXPseudoDestructorExpr(
- Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
- ToQualifierLoc, ToScopeTypeInfo, ToColonColonLoc, ToTildeLoc, Storage);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
- CXXDependentScopeMemberExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
- E->getTemplateKeywordLoc(), E->getFirstQualifierFoundInScope());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- NamedDecl *ToFirstQualifierFoundInScope;
- std::tie(
- ToType, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
- ToFirstQualifierFoundInScope) = *Imp;
- Expr *ToBase = nullptr;
- if (!E->isImplicitAccess()) {
- if (ExpectedExpr ToBaseOrErr = import(E->getBase()))
- ToBase = *ToBaseOrErr;
- else
- return ToBaseOrErr.takeError();
- }
- TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
- if (E->hasExplicitTemplateArgs()) {
- if (Error Err = ImportTemplateArgumentListInfo(
- E->getLAngleLoc(), E->getRAngleLoc(), E->template_arguments(),
- ToTAInfo))
- return std::move(Err);
- ResInfo = &ToTAInfo;
- }
- auto ToMemberNameInfoOrErr = importSeq(E->getMember(), E->getMemberLoc());
- if (!ToMemberNameInfoOrErr)
- return ToMemberNameInfoOrErr.takeError();
- DeclarationNameInfo ToMemberNameInfo(
- std::get<0>(*ToMemberNameInfoOrErr), std::get<1>(*ToMemberNameInfoOrErr));
- // Import additional name location/type info.
- if (Error Err = ImportDeclarationNameLoc(
- E->getMemberNameInfo(), ToMemberNameInfo))
- return std::move(Err);
- return CXXDependentScopeMemberExpr::Create(
- Importer.getToContext(), ToBase, ToType, E->isArrow(), ToOperatorLoc,
- ToQualifierLoc, ToTemplateKeywordLoc, ToFirstQualifierFoundInScope,
- ToMemberNameInfo, ResInfo);
- }
- ExpectedStmt
- ASTNodeImporter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
- auto Imp = importSeq(
- E->getQualifierLoc(), E->getTemplateKeywordLoc(), E->getDeclName(),
- E->getExprLoc(), E->getLAngleLoc(), E->getRAngleLoc());
- if (!Imp)
- return Imp.takeError();
- NestedNameSpecifierLoc ToQualifierLoc;
- SourceLocation ToTemplateKeywordLoc, ToExprLoc, ToLAngleLoc, ToRAngleLoc;
- DeclarationName ToDeclName;
- std::tie(
- ToQualifierLoc, ToTemplateKeywordLoc, ToDeclName, ToExprLoc,
- ToLAngleLoc, ToRAngleLoc) = *Imp;
- DeclarationNameInfo ToNameInfo(ToDeclName, ToExprLoc);
- if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
- return std::move(Err);
- TemplateArgumentListInfo ToTAInfo(ToLAngleLoc, ToRAngleLoc);
- TemplateArgumentListInfo *ResInfo = nullptr;
- if (E->hasExplicitTemplateArgs()) {
- if (Error Err =
- ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
- return std::move(Err);
- ResInfo = &ToTAInfo;
- }
- return DependentScopeDeclRefExpr::Create(
- Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc,
- ToNameInfo, ResInfo);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
- CXXUnresolvedConstructExpr *E) {
- auto Imp = importSeq(
- E->getLParenLoc(), E->getRParenLoc(), E->getTypeSourceInfo());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLParenLoc, ToRParenLoc;
- TypeSourceInfo *ToTypeSourceInfo;
- std::tie(ToLParenLoc, ToRParenLoc, ToTypeSourceInfo) = *Imp;
- SmallVector<Expr *, 8> ToArgs(E->arg_size());
- if (Error Err =
- ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin()))
- return std::move(Err);
- return CXXUnresolvedConstructExpr::Create(
- Importer.getToContext(), ToTypeSourceInfo, ToLParenLoc,
- llvm::makeArrayRef(ToArgs), ToRParenLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
- Expected<CXXRecordDecl *> ToNamingClassOrErr = import(E->getNamingClass());
- if (!ToNamingClassOrErr)
- return ToNamingClassOrErr.takeError();
- auto ToQualifierLocOrErr = import(E->getQualifierLoc());
- if (!ToQualifierLocOrErr)
- return ToQualifierLocOrErr.takeError();
- auto ToNameInfoOrErr = importSeq(E->getName(), E->getNameLoc());
- if (!ToNameInfoOrErr)
- return ToNameInfoOrErr.takeError();
- DeclarationNameInfo ToNameInfo(
- std::get<0>(*ToNameInfoOrErr), std::get<1>(*ToNameInfoOrErr));
- // Import additional name location/type info.
- if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
- return std::move(Err);
- UnresolvedSet<8> ToDecls;
- for (auto *D : E->decls())
- if (auto ToDOrErr = import(D))
- ToDecls.addDecl(cast<NamedDecl>(*ToDOrErr));
- else
- return ToDOrErr.takeError();
- if (E->hasExplicitTemplateArgs() && E->getTemplateKeywordLoc().isValid()) {
- TemplateArgumentListInfo ToTAInfo;
- if (Error Err = ImportTemplateArgumentListInfo(
- E->getLAngleLoc(), E->getRAngleLoc(), E->template_arguments(),
- ToTAInfo))
- return std::move(Err);
- ExpectedSLoc ToTemplateKeywordLocOrErr = import(E->getTemplateKeywordLoc());
- if (!ToTemplateKeywordLocOrErr)
- return ToTemplateKeywordLocOrErr.takeError();
- return UnresolvedLookupExpr::Create(
- Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
- *ToTemplateKeywordLocOrErr, ToNameInfo, E->requiresADL(), &ToTAInfo,
- ToDecls.begin(), ToDecls.end());
- }
- return UnresolvedLookupExpr::Create(
- Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
- ToNameInfo, E->requiresADL(), E->isOverloaded(), ToDecls.begin(),
- ToDecls.end());
- }
- ExpectedStmt
- ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
- auto Imp1 = importSeq(
- E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
- E->getTemplateKeywordLoc());
- if (!Imp1)
- return Imp1.takeError();
- QualType ToType;
- SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
- NestedNameSpecifierLoc ToQualifierLoc;
- std::tie(ToType, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc) = *Imp1;
- auto Imp2 = importSeq(E->getName(), E->getNameLoc());
- if (!Imp2)
- return Imp2.takeError();
- DeclarationNameInfo ToNameInfo(std::get<0>(*Imp2), std::get<1>(*Imp2));
- // Import additional name location/type info.
- if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
- return std::move(Err);
- UnresolvedSet<8> ToDecls;
- for (Decl *D : E->decls())
- if (auto ToDOrErr = import(D))
- ToDecls.addDecl(cast<NamedDecl>(*ToDOrErr));
- else
- return ToDOrErr.takeError();
- TemplateArgumentListInfo ToTAInfo;
- TemplateArgumentListInfo *ResInfo = nullptr;
- if (E->hasExplicitTemplateArgs()) {
- if (Error Err =
- ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
- return std::move(Err);
- ResInfo = &ToTAInfo;
- }
- Expr *ToBase = nullptr;
- if (!E->isImplicitAccess()) {
- if (ExpectedExpr ToBaseOrErr = import(E->getBase()))
- ToBase = *ToBaseOrErr;
- else
- return ToBaseOrErr.takeError();
- }
- return UnresolvedMemberExpr::Create(
- Importer.getToContext(), E->hasUnresolvedUsing(), ToBase, ToType,
- E->isArrow(), ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
- ToNameInfo, ResInfo, ToDecls.begin(), ToDecls.end());
- }
- ExpectedStmt ASTNodeImporter::VisitCallExpr(CallExpr *E) {
- auto Imp = importSeq(E->getCallee(), E->getType(), E->getRParenLoc());
- if (!Imp)
- return Imp.takeError();
- Expr *ToCallee;
- QualType ToType;
- SourceLocation ToRParenLoc;
- std::tie(ToCallee, ToType, ToRParenLoc) = *Imp;
- unsigned NumArgs = E->getNumArgs();
- llvm::SmallVector<Expr *, 2> ToArgs(NumArgs);
- if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
- return std::move(Err);
- if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
- return CXXOperatorCallExpr::Create(
- Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, ToType,
- OCE->getValueKind(), ToRParenLoc, OCE->getFPFeatures(),
- OCE->getADLCallKind());
- }
- return CallExpr::Create(Importer.getToContext(), ToCallee, ToArgs, ToType,
- E->getValueKind(), ToRParenLoc, /*MinNumArgs=*/0,
- E->getADLCallKind());
- }
- ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
- CXXRecordDecl *FromClass = E->getLambdaClass();
- auto ToClassOrErr = import(FromClass);
- if (!ToClassOrErr)
- return ToClassOrErr.takeError();
- CXXRecordDecl *ToClass = *ToClassOrErr;
- // NOTE: lambda classes are created with BeingDefined flag set up.
- // It means that ImportDefinition doesn't work for them and we should fill it
- // manually.
- if (ToClass->isBeingDefined())
- if (Error Err = ImportDeclContext(FromClass, /*ForceImport = */ true))
- return std::move(Err);
- auto ToCallOpOrErr = import(E->getCallOperator());
- if (!ToCallOpOrErr)
- return ToCallOpOrErr.takeError();
- ToClass->completeDefinition();
- SmallVector<LambdaCapture, 8> ToCaptures;
- ToCaptures.reserve(E->capture_size());
- for (const auto &FromCapture : E->captures()) {
- if (auto ToCaptureOrErr = import(FromCapture))
- ToCaptures.push_back(*ToCaptureOrErr);
- else
- return ToCaptureOrErr.takeError();
- }
- SmallVector<Expr *, 8> ToCaptureInits(E->capture_size());
- if (Error Err = ImportContainerChecked(E->capture_inits(), ToCaptureInits))
- return std::move(Err);
- auto Imp = importSeq(
- E->getIntroducerRange(), E->getCaptureDefaultLoc(), E->getEndLoc());
- if (!Imp)
- return Imp.takeError();
- SourceRange ToIntroducerRange;
- SourceLocation ToCaptureDefaultLoc, ToEndLoc;
- std::tie(ToIntroducerRange, ToCaptureDefaultLoc, ToEndLoc) = *Imp;
- return LambdaExpr::Create(
- Importer.getToContext(), ToClass, ToIntroducerRange,
- E->getCaptureDefault(), ToCaptureDefaultLoc, ToCaptures,
- E->hasExplicitParameters(), E->hasExplicitResultType(), ToCaptureInits,
- ToEndLoc, E->containsUnexpandedParameterPack());
- }
- ExpectedStmt ASTNodeImporter::VisitInitListExpr(InitListExpr *E) {
- auto Imp = importSeq(E->getLBraceLoc(), E->getRBraceLoc(), E->getType());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLBraceLoc, ToRBraceLoc;
- QualType ToType;
- std::tie(ToLBraceLoc, ToRBraceLoc, ToType) = *Imp;
- SmallVector<Expr *, 4> ToExprs(E->getNumInits());
- if (Error Err = ImportContainerChecked(E->inits(), ToExprs))
- return std::move(Err);
- ASTContext &ToCtx = Importer.getToContext();
- InitListExpr *To = new (ToCtx) InitListExpr(
- ToCtx, ToLBraceLoc, ToExprs, ToRBraceLoc);
- To->setType(ToType);
- if (E->hasArrayFiller()) {
- if (ExpectedExpr ToFillerOrErr = import(E->getArrayFiller()))
- To->setArrayFiller(*ToFillerOrErr);
- else
- return ToFillerOrErr.takeError();
- }
- if (FieldDecl *FromFD = E->getInitializedFieldInUnion()) {
- if (auto ToFDOrErr = import(FromFD))
- To->setInitializedFieldInUnion(*ToFDOrErr);
- else
- return ToFDOrErr.takeError();
- }
- if (InitListExpr *SyntForm = E->getSyntacticForm()) {
- if (auto ToSyntFormOrErr = import(SyntForm))
- To->setSyntacticForm(*ToSyntFormOrErr);
- else
- return ToSyntFormOrErr.takeError();
- }
- // Copy InitListExprBitfields, which are not handled in the ctor of
- // InitListExpr.
- To->sawArrayRangeDesignator(E->hadArrayRangeDesignator());
- return To;
- }
- ExpectedStmt ASTNodeImporter::VisitCXXStdInitializerListExpr(
- CXXStdInitializerListExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
- if (!ToSubExprOrErr)
- return ToSubExprOrErr.takeError();
- return new (Importer.getToContext()) CXXStdInitializerListExpr(
- *ToTypeOrErr, *ToSubExprOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXInheritedCtorInitExpr(
- CXXInheritedCtorInitExpr *E) {
- auto Imp = importSeq(E->getLocation(), E->getType(), E->getConstructor());
- if (!Imp)
- return Imp.takeError();
- SourceLocation ToLocation;
- QualType ToType;
- CXXConstructorDecl *ToConstructor;
- std::tie(ToLocation, ToType, ToConstructor) = *Imp;
- return new (Importer.getToContext()) CXXInheritedCtorInitExpr(
- ToLocation, ToType, ToConstructor, E->constructsVBase(),
- E->inheritedFromVBase());
- }
- ExpectedStmt ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
- auto Imp = importSeq(E->getType(), E->getCommonExpr(), E->getSubExpr());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- Expr *ToCommonExpr, *ToSubExpr;
- std::tie(ToType, ToCommonExpr, ToSubExpr) = *Imp;
- return new (Importer.getToContext()) ArrayInitLoopExpr(
- ToType, ToCommonExpr, ToSubExpr);
- }
- ExpectedStmt ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- return new (Importer.getToContext()) ArrayInitIndexExpr(*ToTypeOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
- ExpectedSLoc ToBeginLocOrErr = import(E->getBeginLoc());
- if (!ToBeginLocOrErr)
- return ToBeginLocOrErr.takeError();
- auto ToFieldOrErr = import(E->getField());
- if (!ToFieldOrErr)
- return ToFieldOrErr.takeError();
- auto UsedContextOrErr = Importer.ImportContext(E->getUsedContext());
- if (!UsedContextOrErr)
- return UsedContextOrErr.takeError();
- return CXXDefaultInitExpr::Create(
- Importer.getToContext(), *ToBeginLocOrErr, *ToFieldOrErr, *UsedContextOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getSubExpr(), E->getTypeInfoAsWritten(),
- E->getOperatorLoc(), E->getRParenLoc(), E->getAngleBrackets());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- Expr *ToSubExpr;
- TypeSourceInfo *ToTypeInfoAsWritten;
- SourceLocation ToOperatorLoc, ToRParenLoc;
- SourceRange ToAngleBrackets;
- std::tie(
- ToType, ToSubExpr, ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc,
- ToAngleBrackets) = *Imp;
- ExprValueKind VK = E->getValueKind();
- CastKind CK = E->getCastKind();
- auto ToBasePathOrErr = ImportCastPath(E);
- if (!ToBasePathOrErr)
- return ToBasePathOrErr.takeError();
- if (isa<CXXStaticCastExpr>(E)) {
- return CXXStaticCastExpr::Create(
- Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
- ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
- } else if (isa<CXXDynamicCastExpr>(E)) {
- return CXXDynamicCastExpr::Create(
- Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
- ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
- } else if (isa<CXXReinterpretCastExpr>(E)) {
- return CXXReinterpretCastExpr::Create(
- Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
- ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
- } else if (isa<CXXConstCastExpr>(E)) {
- return CXXConstCastExpr::Create(
- Importer.getToContext(), ToType, VK, ToSubExpr, ToTypeInfoAsWritten,
- ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
- } else {
- llvm_unreachable("Unknown cast type");
- return make_error<ImportError>();
- }
- }
- ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getExprLoc(), E->getParameter(), E->getReplacement());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- SourceLocation ToExprLoc;
- NonTypeTemplateParmDecl *ToParameter;
- Expr *ToReplacement;
- std::tie(ToType, ToExprLoc, ToParameter, ToReplacement) = *Imp;
- return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
- ToType, E->getValueKind(), ToExprLoc, ToParameter, ToReplacement);
- }
- ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->getBeginLoc(), E->getEndLoc());
- if (!Imp)
- return Imp.takeError();
- QualType ToType;
- SourceLocation ToBeginLoc, ToEndLoc;
- std::tie(ToType, ToBeginLoc, ToEndLoc) = *Imp;
- SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs());
- if (Error Err = ImportContainerChecked(E->getArgs(), ToArgs))
- return std::move(Err);
- // According to Sema::BuildTypeTrait(), if E is value-dependent,
- // Value is always false.
- bool ToValue = (E->isValueDependent() ? false : E->getValue());
- return TypeTraitExpr::Create(
- Importer.getToContext(), ToType, ToBeginLoc, E->getTrait(), ToArgs,
- ToEndLoc, ToValue);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
- ExpectedType ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- auto ToSourceRangeOrErr = import(E->getSourceRange());
- if (!ToSourceRangeOrErr)
- return ToSourceRangeOrErr.takeError();
- if (E->isTypeOperand()) {
- if (auto ToTSIOrErr = import(E->getTypeOperandSourceInfo()))
- return new (Importer.getToContext()) CXXTypeidExpr(
- *ToTypeOrErr, *ToTSIOrErr, *ToSourceRangeOrErr);
- else
- return ToTSIOrErr.takeError();
- }
- ExpectedExpr ToExprOperandOrErr = import(E->getExprOperand());
- if (!ToExprOperandOrErr)
- return ToExprOperandOrErr.takeError();
- return new (Importer.getToContext()) CXXTypeidExpr(
- *ToTypeOrErr, *ToExprOperandOrErr, *ToSourceRangeOrErr);
- }
- void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
- CXXMethodDecl *FromMethod) {
- for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) {
- if (auto ImportedOrErr = import(FromOverriddenMethod))
- ToMethod->getCanonicalDecl()->addOverriddenMethod(cast<CXXMethodDecl>(
- (*ImportedOrErr)->getCanonicalDecl()));
- else
- consumeError(ImportedOrErr.takeError());
- }
- }
- ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
- ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport,
- ASTImporterLookupTable *LookupTable)
- : LookupTable(LookupTable), ToContext(ToContext), FromContext(FromContext),
- ToFileManager(ToFileManager), FromFileManager(FromFileManager),
- Minimal(MinimalImport) {
- ImportedDecls[FromContext.getTranslationUnitDecl()] =
- ToContext.getTranslationUnitDecl();
- }
- ASTImporter::~ASTImporter() = default;
- Optional<unsigned> ASTImporter::getFieldIndex(Decl *F) {
- assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
- "Try to get field index for non-field.");
- auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
- if (!Owner)
- return None;
- unsigned Index = 0;
- for (const auto *D : Owner->decls()) {
- if (D == F)
- return Index;
- if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
- ++Index;
- }
- llvm_unreachable("Field was not found in its parent context.");
- return None;
- }
- ASTImporter::FoundDeclsTy
- ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) {
- // We search in the redecl context because of transparent contexts.
- // E.g. a simple C language enum is a transparent context:
- // enum E { A, B };
- // Now if we had a global variable in the TU
- // int A;
- // then the enum constant 'A' and the variable 'A' violates ODR.
- // We can diagnose this only if we search in the redecl context.
- DeclContext *ReDC = DC->getRedeclContext();
- if (LookupTable) {
- ASTImporterLookupTable::LookupResult LookupResult =
- LookupTable->lookup(ReDC, Name);
- return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
- } else {
- // FIXME Can we remove this kind of lookup?
- // Or lldb really needs this C/C++ lookup?
- FoundDeclsTy Result;
- ReDC->localUncachedLookup(Name, Result);
- return Result;
- }
- }
- void ASTImporter::AddToLookupTable(Decl *ToD) {
- if (LookupTable)
- if (auto *ToND = dyn_cast<NamedDecl>(ToD))
- LookupTable->add(ToND);
- }
- Expected<Decl *> ASTImporter::ImportImpl(Decl *FromD) {
- // Import the decl using ASTNodeImporter.
- ASTNodeImporter Importer(*this);
- return Importer.Visit(FromD);
- }
- void ASTImporter::RegisterImportedDecl(Decl *FromD, Decl *ToD) {
- MapImported(FromD, ToD);
- AddToLookupTable(ToD);
- }
- Expected<QualType> ASTImporter::Import(QualType FromT) {
- if (FromT.isNull())
- return QualType{};
- const Type *FromTy = FromT.getTypePtr();
- // Check whether we've already imported this type.
- llvm::DenseMap<const Type *, const Type *>::iterator Pos
- = ImportedTypes.find(FromTy);
- if (Pos != ImportedTypes.end())
- return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers());
- // Import the type
- ASTNodeImporter Importer(*this);
- ExpectedType ToTOrErr = Importer.Visit(FromTy);
- if (!ToTOrErr)
- return ToTOrErr.takeError();
- // Record the imported type.
- ImportedTypes[FromTy] = (*ToTOrErr).getTypePtr();
- return ToContext.getQualifiedType(*ToTOrErr, FromT.getLocalQualifiers());
- }
- Expected<TypeSourceInfo *> ASTImporter::Import(TypeSourceInfo *FromTSI) {
- if (!FromTSI)
- return FromTSI;
- // FIXME: For now we just create a "trivial" type source info based
- // on the type and a single location. Implement a real version of this.
- ExpectedType TOrErr = Import(FromTSI->getType());
- if (!TOrErr)
- return TOrErr.takeError();
- ExpectedSLoc BeginLocOrErr = Import(FromTSI->getTypeLoc().getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- return ToContext.getTrivialTypeSourceInfo(*TOrErr, *BeginLocOrErr);
- }
- Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
- Attr *ToAttr = FromAttr->clone(ToContext);
- if (auto ToRangeOrErr = Import(FromAttr->getRange()))
- ToAttr->setRange(*ToRangeOrErr);
- else
- return ToRangeOrErr.takeError();
- return ToAttr;
- }
- Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
- auto Pos = ImportedDecls.find(FromD);
- if (Pos != ImportedDecls.end())
- return Pos->second;
- else
- return nullptr;
- }
- TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) {
- auto FromDPos = ImportedFromDecls.find(ToD);
- if (FromDPos == ImportedFromDecls.end())
- return nullptr;
- return FromDPos->second->getTranslationUnitDecl();
- }
- Expected<Decl *> ASTImporter::Import(Decl *FromD) {
- if (!FromD)
- return nullptr;
- // Check whether we've already imported this declaration.
- Decl *ToD = GetAlreadyImportedOrNull(FromD);
- if (ToD) {
- // If FromD has some updated flags after last import, apply it
- updateFlags(FromD, ToD);
- return ToD;
- }
- // Import the declaration.
- ExpectedDecl ToDOrErr = ImportImpl(FromD);
- if (!ToDOrErr)
- return ToDOrErr;
- ToD = *ToDOrErr;
- // FIXME Use getImportDeclErrorIfAny() here (and return with the error) once
- // the error handling is finished in GetImportedOrCreateSpecialDecl().
- if (!ToD) {
- return nullptr;
- }
- // Make sure that ImportImpl registered the imported decl.
- assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
- // Once the decl is connected to the existing declarations, i.e. when the
- // redecl chain is properly set then we populate the lookup again.
- // This way the primary context will be able to find all decls.
- AddToLookupTable(ToD);
- // Notify subclasses.
- Imported(FromD, ToD);
- updateFlags(FromD, ToD);
- return ToDOrErr;
- }
- Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
- if (!FromDC)
- return FromDC;
- ExpectedDecl ToDCOrErr = Import(cast<Decl>(FromDC));
- if (!ToDCOrErr)
- return ToDCOrErr.takeError();
- auto *ToDC = cast<DeclContext>(*ToDCOrErr);
- // When we're using a record/enum/Objective-C class/protocol as a context, we
- // need it to have a definition.
- if (auto *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
- auto *FromRecord = cast<RecordDecl>(FromDC);
- if (ToRecord->isCompleteDefinition()) {
- // Do nothing.
- } else if (FromRecord->isCompleteDefinition()) {
- if (Error Err = ASTNodeImporter(*this).ImportDefinition(
- FromRecord, ToRecord, ASTNodeImporter::IDK_Basic))
- return std::move(Err);
- } else {
- CompleteDecl(ToRecord);
- }
- } else if (auto *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
- auto *FromEnum = cast<EnumDecl>(FromDC);
- if (ToEnum->isCompleteDefinition()) {
- // Do nothing.
- } else if (FromEnum->isCompleteDefinition()) {
- if (Error Err = ASTNodeImporter(*this).ImportDefinition(
- FromEnum, ToEnum, ASTNodeImporter::IDK_Basic))
- return std::move(Err);
- } else {
- CompleteDecl(ToEnum);
- }
- } else if (auto *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
- auto *FromClass = cast<ObjCInterfaceDecl>(FromDC);
- if (ToClass->getDefinition()) {
- // Do nothing.
- } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
- if (Error Err = ASTNodeImporter(*this).ImportDefinition(
- FromDef, ToClass, ASTNodeImporter::IDK_Basic))
- return std::move(Err);
- } else {
- CompleteDecl(ToClass);
- }
- } else if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
- auto *FromProto = cast<ObjCProtocolDecl>(FromDC);
- if (ToProto->getDefinition()) {
- // Do nothing.
- } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
- if (Error Err = ASTNodeImporter(*this).ImportDefinition(
- FromDef, ToProto, ASTNodeImporter::IDK_Basic))
- return std::move(Err);
- } else {
- CompleteDecl(ToProto);
- }
- }
- return ToDC;
- }
- Expected<Expr *> ASTImporter::Import(Expr *FromE) {
- if (ExpectedStmt ToSOrErr = Import(cast_or_null<Stmt>(FromE)))
- return cast_or_null<Expr>(*ToSOrErr);
- else
- return ToSOrErr.takeError();
- }
- Expected<Stmt *> ASTImporter::Import(Stmt *FromS) {
- if (!FromS)
- return nullptr;
- // Check whether we've already imported this statement.
- llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
- if (Pos != ImportedStmts.end())
- return Pos->second;
- // Import the statement.
- ASTNodeImporter Importer(*this);
- ExpectedStmt ToSOrErr = Importer.Visit(FromS);
- if (!ToSOrErr)
- return ToSOrErr;
- if (auto *ToE = dyn_cast<Expr>(*ToSOrErr)) {
- auto *FromE = cast<Expr>(FromS);
- // Copy ExprBitfields, which may not be handled in Expr subclasses
- // constructors.
- ToE->setValueKind(FromE->getValueKind());
- ToE->setObjectKind(FromE->getObjectKind());
- ToE->setTypeDependent(FromE->isTypeDependent());
- ToE->setValueDependent(FromE->isValueDependent());
- ToE->setInstantiationDependent(FromE->isInstantiationDependent());
- ToE->setContainsUnexpandedParameterPack(
- FromE->containsUnexpandedParameterPack());
- }
- // Record the imported statement object.
- ImportedStmts[FromS] = *ToSOrErr;
- return ToSOrErr;
- }
- Expected<NestedNameSpecifier *>
- ASTImporter::Import(NestedNameSpecifier *FromNNS) {
- if (!FromNNS)
- return nullptr;
- NestedNameSpecifier *Prefix;
- if (Error Err = importInto(Prefix, FromNNS->getPrefix()))
- return std::move(Err);
- switch (FromNNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- assert(FromNNS->getAsIdentifier() && "NNS should contain identifier.");
- return NestedNameSpecifier::Create(ToContext, Prefix,
- Import(FromNNS->getAsIdentifier()));
- case NestedNameSpecifier::Namespace:
- if (ExpectedDecl NSOrErr = Import(FromNNS->getAsNamespace())) {
- return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceDecl>(*NSOrErr));
- } else
- return NSOrErr.takeError();
- case NestedNameSpecifier::NamespaceAlias:
- if (ExpectedDecl NSADOrErr = Import(FromNNS->getAsNamespaceAlias()))
- return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceAliasDecl>(*NSADOrErr));
- else
- return NSADOrErr.takeError();
- case NestedNameSpecifier::Global:
- return NestedNameSpecifier::GlobalSpecifier(ToContext);
- case NestedNameSpecifier::Super:
- if (ExpectedDecl RDOrErr = Import(FromNNS->getAsRecordDecl()))
- return NestedNameSpecifier::SuperSpecifier(ToContext,
- cast<CXXRecordDecl>(*RDOrErr));
- else
- return RDOrErr.takeError();
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- if (Expected<QualType> TyOrErr =
- Import(QualType(FromNNS->getAsType(), 0u))) {
- bool TSTemplate =
- FromNNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate;
- return NestedNameSpecifier::Create(ToContext, Prefix, TSTemplate,
- TyOrErr->getTypePtr());
- } else {
- return TyOrErr.takeError();
- }
- }
- llvm_unreachable("Invalid nested name specifier kind");
- }
- Expected<NestedNameSpecifierLoc>
- ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
- // Copied from NestedNameSpecifier mostly.
- SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
- NestedNameSpecifierLoc NNS = FromNNS;
- // Push each of the nested-name-specifiers's onto a stack for
- // serialization in reverse order.
- while (NNS) {
- NestedNames.push_back(NNS);
- NNS = NNS.getPrefix();
- }
- NestedNameSpecifierLocBuilder Builder;
- while (!NestedNames.empty()) {
- NNS = NestedNames.pop_back_val();
- NestedNameSpecifier *Spec = nullptr;
- if (Error Err = importInto(Spec, NNS.getNestedNameSpecifier()))
- return std::move(Err);
- NestedNameSpecifier::SpecifierKind Kind = Spec->getKind();
- SourceLocation ToLocalBeginLoc, ToLocalEndLoc;
- if (Kind != NestedNameSpecifier::Super) {
- if (Error Err = importInto(ToLocalBeginLoc, NNS.getLocalBeginLoc()))
- return std::move(Err);
- if (Kind != NestedNameSpecifier::Global)
- if (Error Err = importInto(ToLocalEndLoc, NNS.getLocalEndLoc()))
- return std::move(Err);
- }
- switch (Kind) {
- case NestedNameSpecifier::Identifier:
- Builder.Extend(getToContext(), Spec->getAsIdentifier(), ToLocalBeginLoc,
- ToLocalEndLoc);
- break;
- case NestedNameSpecifier::Namespace:
- Builder.Extend(getToContext(), Spec->getAsNamespace(), ToLocalBeginLoc,
- ToLocalEndLoc);
- break;
- case NestedNameSpecifier::NamespaceAlias:
- Builder.Extend(getToContext(), Spec->getAsNamespaceAlias(),
- ToLocalBeginLoc, ToLocalEndLoc);
- break;
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- SourceLocation ToTLoc;
- if (Error Err = importInto(ToTLoc, NNS.getTypeLoc().getBeginLoc()))
- return std::move(Err);
- TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo(
- QualType(Spec->getAsType(), 0), ToTLoc);
- Builder.Extend(getToContext(), ToLocalBeginLoc, TSI->getTypeLoc(),
- ToLocalEndLoc);
- break;
- }
- case NestedNameSpecifier::Global:
- Builder.MakeGlobal(getToContext(), ToLocalBeginLoc);
- break;
- case NestedNameSpecifier::Super: {
- auto ToSourceRangeOrErr = Import(NNS.getSourceRange());
- if (!ToSourceRangeOrErr)
- return ToSourceRangeOrErr.takeError();
- Builder.MakeSuper(getToContext(), Spec->getAsRecordDecl(),
- ToSourceRangeOrErr->getBegin(),
- ToSourceRangeOrErr->getEnd());
- }
- }
- }
- return Builder.getWithLocInContext(getToContext());
- }
- Expected<TemplateName> ASTImporter::Import(TemplateName From) {
- switch (From.getKind()) {
- case TemplateName::Template:
- if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl()))
- return TemplateName(cast<TemplateDecl>(*ToTemplateOrErr));
- else
- return ToTemplateOrErr.takeError();
- case TemplateName::OverloadedTemplate: {
- OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
- UnresolvedSet<2> ToTemplates;
- for (auto *I : *FromStorage) {
- if (auto ToOrErr = Import(I))
- ToTemplates.addDecl(cast<NamedDecl>(*ToOrErr));
- else
- return ToOrErr.takeError();
- }
- return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
- ToTemplates.end());
- }
- case TemplateName::AssumedTemplate: {
- AssumedTemplateStorage *FromStorage = From.getAsAssumedTemplateName();
- auto DeclNameOrErr = Import(FromStorage->getDeclName());
- if (!DeclNameOrErr)
- return DeclNameOrErr.takeError();
- return ToContext.getAssumedTemplateName(*DeclNameOrErr);
- }
- case TemplateName::QualifiedTemplate: {
- QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
- auto QualifierOrErr = Import(QTN->getQualifier());
- if (!QualifierOrErr)
- return QualifierOrErr.takeError();
- if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl()))
- return ToContext.getQualifiedTemplateName(
- *QualifierOrErr, QTN->hasTemplateKeyword(),
- cast<TemplateDecl>(*ToTemplateOrErr));
- else
- return ToTemplateOrErr.takeError();
- }
- case TemplateName::DependentTemplate: {
- DependentTemplateName *DTN = From.getAsDependentTemplateName();
- auto QualifierOrErr = Import(DTN->getQualifier());
- if (!QualifierOrErr)
- return QualifierOrErr.takeError();
- if (DTN->isIdentifier()) {
- return ToContext.getDependentTemplateName(*QualifierOrErr,
- Import(DTN->getIdentifier()));
- }
- return ToContext.getDependentTemplateName(*QualifierOrErr,
- DTN->getOperator());
- }
- case TemplateName::SubstTemplateTemplateParm: {
- SubstTemplateTemplateParmStorage *Subst =
- From.getAsSubstTemplateTemplateParm();
- ExpectedDecl ParamOrErr = Import(Subst->getParameter());
- if (!ParamOrErr)
- return ParamOrErr.takeError();
- auto ReplacementOrErr = Import(Subst->getReplacement());
- if (!ReplacementOrErr)
- return ReplacementOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParm(
- cast<TemplateTemplateParmDecl>(*ParamOrErr), *ReplacementOrErr);
- }
- case TemplateName::SubstTemplateTemplateParmPack: {
- SubstTemplateTemplateParmPackStorage *SubstPack
- = From.getAsSubstTemplateTemplateParmPack();
- ExpectedDecl ParamOrErr = Import(SubstPack->getParameterPack());
- if (!ParamOrErr)
- return ParamOrErr.takeError();
- ASTNodeImporter Importer(*this);
- auto ArgPackOrErr =
- Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
- if (!ArgPackOrErr)
- return ArgPackOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParmPack(
- cast<TemplateTemplateParmDecl>(*ParamOrErr), *ArgPackOrErr);
- }
- }
- llvm_unreachable("Invalid template name kind");
- }
- Expected<SourceLocation> ASTImporter::Import(SourceLocation FromLoc) {
- if (FromLoc.isInvalid())
- return SourceLocation{};
- SourceManager &FromSM = FromContext.getSourceManager();
- bool IsBuiltin = FromSM.isWrittenInBuiltinFile(FromLoc);
- std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
- Expected<FileID> ToFileIDOrErr = Import(Decomposed.first, IsBuiltin);
- if (!ToFileIDOrErr)
- return ToFileIDOrErr.takeError();
- SourceManager &ToSM = ToContext.getSourceManager();
- return ToSM.getComposedLoc(*ToFileIDOrErr, Decomposed.second);
- }
- Expected<SourceRange> ASTImporter::Import(SourceRange FromRange) {
- SourceLocation ToBegin, ToEnd;
- if (Error Err = importInto(ToBegin, FromRange.getBegin()))
- return std::move(Err);
- if (Error Err = importInto(ToEnd, FromRange.getEnd()))
- return std::move(Err);
- return SourceRange(ToBegin, ToEnd);
- }
- Expected<FileID> ASTImporter::Import(FileID FromID, bool IsBuiltin) {
- llvm::DenseMap<FileID, FileID>::iterator Pos = ImportedFileIDs.find(FromID);
- if (Pos != ImportedFileIDs.end())
- return Pos->second;
- SourceManager &FromSM = FromContext.getSourceManager();
- SourceManager &ToSM = ToContext.getSourceManager();
- const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
- // Map the FromID to the "to" source manager.
- FileID ToID;
- if (FromSLoc.isExpansion()) {
- const SrcMgr::ExpansionInfo &FromEx = FromSLoc.getExpansion();
- ExpectedSLoc ToSpLoc = Import(FromEx.getSpellingLoc());
- if (!ToSpLoc)
- return ToSpLoc.takeError();
- ExpectedSLoc ToExLocS = Import(FromEx.getExpansionLocStart());
- if (!ToExLocS)
- return ToExLocS.takeError();
- unsigned TokenLen = FromSM.getFileIDSize(FromID);
- SourceLocation MLoc;
- if (FromEx.isMacroArgExpansion()) {
- MLoc = ToSM.createMacroArgExpansionLoc(*ToSpLoc, *ToExLocS, TokenLen);
- } else {
- if (ExpectedSLoc ToExLocE = Import(FromEx.getExpansionLocEnd()))
- MLoc = ToSM.createExpansionLoc(*ToSpLoc, *ToExLocS, *ToExLocE, TokenLen,
- FromEx.isExpansionTokenRange());
- else
- return ToExLocE.takeError();
- }
- ToID = ToSM.getFileID(MLoc);
- } else {
- const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (!IsBuiltin) {
- // Include location of this file.
- ExpectedSLoc ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
- if (!ToIncludeLoc)
- return ToIncludeLoc.takeError();
- if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
- // FIXME: We probably want to use getVirtualFile(), so we don't hit the
- // disk again
- // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
- // than mmap the files several times.
- const FileEntry *Entry =
- ToFileManager.getFile(Cache->OrigEntry->getName());
- // FIXME: The filename may be a virtual name that does probably not
- // point to a valid file and we get no Entry here. In this case try with
- // the memory buffer below.
- if (Entry)
- ToID = ToSM.createFileID(Entry, *ToIncludeLoc,
- FromSLoc.getFile().getFileCharacteristic());
- }
- }
- if (ToID.isInvalid() || IsBuiltin) {
- // FIXME: We want to re-use the existing MemoryBuffer!
- bool Invalid = true;
- const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(
- FromContext.getDiagnostics(), FromSM, SourceLocation{}, &Invalid);
- if (!FromBuf || Invalid)
- // FIXME: Use a new error kind?
- return llvm::make_error<ImportError>(ImportError::Unknown);
- std::unique_ptr<llvm::MemoryBuffer> ToBuf =
- llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
- FromBuf->getBufferIdentifier());
- ToID = ToSM.createFileID(std::move(ToBuf),
- FromSLoc.getFile().getFileCharacteristic());
- }
- }
- assert(ToID.isValid() && "Unexpected invalid fileID was created.");
- ImportedFileIDs[FromID] = ToID;
- return ToID;
- }
- Expected<CXXCtorInitializer *> ASTImporter::Import(CXXCtorInitializer *From) {
- ExpectedExpr ToExprOrErr = Import(From->getInit());
- if (!ToExprOrErr)
- return ToExprOrErr.takeError();
- auto LParenLocOrErr = Import(From->getLParenLoc());
- if (!LParenLocOrErr)
- return LParenLocOrErr.takeError();
- auto RParenLocOrErr = Import(From->getRParenLoc());
- if (!RParenLocOrErr)
- return RParenLocOrErr.takeError();
- if (From->isBaseInitializer()) {
- auto ToTInfoOrErr = Import(From->getTypeSourceInfo());
- if (!ToTInfoOrErr)
- return ToTInfoOrErr.takeError();
- SourceLocation EllipsisLoc;
- if (From->isPackExpansion())
- if (Error Err = importInto(EllipsisLoc, From->getEllipsisLoc()))
- return std::move(Err);
- return new (ToContext) CXXCtorInitializer(
- ToContext, *ToTInfoOrErr, From->isBaseVirtual(), *LParenLocOrErr,
- *ToExprOrErr, *RParenLocOrErr, EllipsisLoc);
- } else if (From->isMemberInitializer()) {
- ExpectedDecl ToFieldOrErr = Import(From->getMember());
- if (!ToFieldOrErr)
- return ToFieldOrErr.takeError();
- auto MemberLocOrErr = Import(From->getMemberLocation());
- if (!MemberLocOrErr)
- return MemberLocOrErr.takeError();
- return new (ToContext) CXXCtorInitializer(
- ToContext, cast_or_null<FieldDecl>(*ToFieldOrErr), *MemberLocOrErr,
- *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
- } else if (From->isIndirectMemberInitializer()) {
- ExpectedDecl ToIFieldOrErr = Import(From->getIndirectMember());
- if (!ToIFieldOrErr)
- return ToIFieldOrErr.takeError();
- auto MemberLocOrErr = Import(From->getMemberLocation());
- if (!MemberLocOrErr)
- return MemberLocOrErr.takeError();
- return new (ToContext) CXXCtorInitializer(
- ToContext, cast_or_null<IndirectFieldDecl>(*ToIFieldOrErr),
- *MemberLocOrErr, *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
- } else if (From->isDelegatingInitializer()) {
- auto ToTInfoOrErr = Import(From->getTypeSourceInfo());
- if (!ToTInfoOrErr)
- return ToTInfoOrErr.takeError();
- return new (ToContext)
- CXXCtorInitializer(ToContext, *ToTInfoOrErr, *LParenLocOrErr,
- *ToExprOrErr, *RParenLocOrErr);
- } else {
- // FIXME: assert?
- return make_error<ImportError>();
- }
- }
- Expected<CXXBaseSpecifier *>
- ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
- auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec);
- if (Pos != ImportedCXXBaseSpecifiers.end())
- return Pos->second;
- Expected<SourceRange> ToSourceRange = Import(BaseSpec->getSourceRange());
- if (!ToSourceRange)
- return ToSourceRange.takeError();
- Expected<TypeSourceInfo *> ToTSI = Import(BaseSpec->getTypeSourceInfo());
- if (!ToTSI)
- return ToTSI.takeError();
- ExpectedSLoc ToEllipsisLoc = Import(BaseSpec->getEllipsisLoc());
- if (!ToEllipsisLoc)
- return ToEllipsisLoc.takeError();
- CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier(
- *ToSourceRange, BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
- BaseSpec->getAccessSpecifierAsWritten(), *ToTSI, *ToEllipsisLoc);
- ImportedCXXBaseSpecifiers[BaseSpec] = Imported;
- return Imported;
- }
- Error ASTImporter::ImportDefinition(Decl *From) {
- ExpectedDecl ToOrErr = Import(From);
- if (!ToOrErr)
- return ToOrErr.takeError();
- Decl *To = *ToOrErr;
- auto *FromDC = cast<DeclContext>(From);
- ASTNodeImporter Importer(*this);
- if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
- if (!ToRecord->getDefinition()) {
- return Importer.ImportDefinition(
- cast<RecordDecl>(FromDC), ToRecord,
- ASTNodeImporter::IDK_Everything);
- }
- }
- if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
- if (!ToEnum->getDefinition()) {
- return Importer.ImportDefinition(
- cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
- }
- }
- if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
- if (!ToIFace->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCInterfaceDecl>(FromDC), ToIFace,
- ASTNodeImporter::IDK_Everything);
- }
- }
- if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
- if (!ToProto->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCProtocolDecl>(FromDC), ToProto,
- ASTNodeImporter::IDK_Everything);
- }
- }
- return Importer.ImportDeclContext(FromDC, true);
- }
- Expected<DeclarationName> ASTImporter::Import(DeclarationName FromName) {
- if (!FromName)
- return DeclarationName{};
- switch (FromName.getNameKind()) {
- case DeclarationName::Identifier:
- return DeclarationName(Import(FromName.getAsIdentifierInfo()));
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- if (auto ToSelOrErr = Import(FromName.getObjCSelector()))
- return DeclarationName(*ToSelOrErr);
- else
- return ToSelOrErr.takeError();
- case DeclarationName::CXXConstructorName: {
- if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
- return ToContext.DeclarationNames.getCXXConstructorName(
- ToContext.getCanonicalType(*ToTyOrErr));
- else
- return ToTyOrErr.takeError();
- }
- case DeclarationName::CXXDestructorName: {
- if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
- return ToContext.DeclarationNames.getCXXDestructorName(
- ToContext.getCanonicalType(*ToTyOrErr));
- else
- return ToTyOrErr.takeError();
- }
- case DeclarationName::CXXDeductionGuideName: {
- if (auto ToTemplateOrErr = Import(FromName.getCXXDeductionGuideTemplate()))
- return ToContext.DeclarationNames.getCXXDeductionGuideName(
- cast<TemplateDecl>(*ToTemplateOrErr));
- else
- return ToTemplateOrErr.takeError();
- }
- case DeclarationName::CXXConversionFunctionName: {
- if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
- return ToContext.DeclarationNames.getCXXConversionFunctionName(
- ToContext.getCanonicalType(*ToTyOrErr));
- else
- return ToTyOrErr.takeError();
- }
- case DeclarationName::CXXOperatorName:
- return ToContext.DeclarationNames.getCXXOperatorName(
- FromName.getCXXOverloadedOperator());
- case DeclarationName::CXXLiteralOperatorName:
- return ToContext.DeclarationNames.getCXXLiteralOperatorName(
- Import(FromName.getCXXLiteralIdentifier()));
- case DeclarationName::CXXUsingDirective:
- // FIXME: STATICS!
- return DeclarationName::getUsingDirectiveName();
- }
- llvm_unreachable("Invalid DeclarationName Kind!");
- }
- IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
- if (!FromId)
- return nullptr;
- IdentifierInfo *ToId = &ToContext.Idents.get(FromId->getName());
- if (!ToId->getBuiltinID() && FromId->getBuiltinID())
- ToId->setBuiltinID(FromId->getBuiltinID());
- return ToId;
- }
- Expected<Selector> ASTImporter::Import(Selector FromSel) {
- if (FromSel.isNull())
- return Selector{};
- SmallVector<IdentifierInfo *, 4> Idents;
- Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
- for (unsigned I = 1, N = FromSel.getNumArgs(); I < N; ++I)
- Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(I)));
- return ToContext.Selectors.getSelector(FromSel.getNumArgs(), Idents.data());
- }
- DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
- DeclContext *DC,
- unsigned IDNS,
- NamedDecl **Decls,
- unsigned NumDecls) {
- return Name;
- }
- DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
- if (LastDiagFromFrom)
- ToContext.getDiagnostics().notePriorDiagnosticFrom(
- FromContext.getDiagnostics());
- LastDiagFromFrom = false;
- return ToContext.getDiagnostics().Report(Loc, DiagID);
- }
- DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
- if (!LastDiagFromFrom)
- FromContext.getDiagnostics().notePriorDiagnosticFrom(
- ToContext.getDiagnostics());
- LastDiagFromFrom = true;
- return FromContext.getDiagnostics().Report(Loc, DiagID);
- }
- void ASTImporter::CompleteDecl (Decl *D) {
- if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
- if (!ID->getDefinition())
- ID->startDefinition();
- }
- else if (auto *PD = dyn_cast<ObjCProtocolDecl>(D)) {
- if (!PD->getDefinition())
- PD->startDefinition();
- }
- else if (auto *TD = dyn_cast<TagDecl>(D)) {
- if (!TD->getDefinition() && !TD->isBeingDefined()) {
- TD->startDefinition();
- TD->setCompleteDefinition(true);
- }
- }
- else {
- assert(0 && "CompleteDecl called on a Decl that can't be completed");
- }
- }
- Decl *ASTImporter::MapImported(Decl *From, Decl *To) {
- llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(From);
- assert((Pos == ImportedDecls.end() || Pos->second == To) &&
- "Try to import an already imported Decl");
- if (Pos != ImportedDecls.end())
- return Pos->second;
- ImportedDecls[From] = To;
- // This mapping should be maintained only in this function. Therefore do not
- // check for additional consistency.
- ImportedFromDecls[To] = From;
- return To;
- }
- bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
- bool Complain) {
- llvm::DenseMap<const Type *, const Type *>::iterator Pos =
- ImportedTypes.find(From.getTypePtr());
- if (Pos != ImportedTypes.end()) {
- if (ExpectedType ToFromOrErr = Import(From)) {
- if (ToContext.hasSameType(*ToFromOrErr, To))
- return true;
- } else {
- llvm::consumeError(ToFromOrErr.takeError());
- }
- }
- StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
- getStructuralEquivalenceKind(*this), false,
- Complain);
- return Ctx.IsEquivalent(From, To);
- }
|