12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764 |
- //===- 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/ASTImporterSharedState.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/Builtins.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/ScopeExit.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 ExpectedTypePtr = llvm::Expected<const Type *>;
- 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>;
- using ExpectedName = llvm::Expected<DeclarationName>;
- 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>
- auto import(T *From)
- -> std::conditional_t<std::is_base_of<Type, T>::value,
- Expected<const T *>, Expected<T *>> {
- auto ToOrErr = Importer.Import(From);
- if (!ToOrErr)
- return ToOrErr.takeError();
- return cast_or_null<T>(*ToOrErr);
- }
- template <typename T>
- auto 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);
- }
- ExplicitSpecifier importExplicitSpecifier(Error &Err,
- ExplicitSpecifier ESpec);
- // Wrapper for an overload set.
- template <typename ToDeclT> struct CallOverloadedCreateFun {
- template <typename... Args> decltype(auto) operator()(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) {
- 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->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;
- }
- void addDeclToContexts(Decl *FromD, Decl *ToD) {
- if (Importer.isMinimalImport()) {
- // In minimal import case the decl must be added even if it is not
- // contained in original context, for LLDB compatibility.
- // FIXME: Check if a better solution is possible.
- if (!FromD->getDescribedTemplate() &&
- FromD->getFriendObjectKind() == Decl::FOK_None)
- ToD->getLexicalDeclContext()->addDeclInternal(ToD);
- return;
- }
- DeclContext *FromDC = FromD->getDeclContext();
- DeclContext *FromLexicalDC = FromD->getLexicalDeclContext();
- DeclContext *ToDC = ToD->getDeclContext();
- DeclContext *ToLexicalDC = ToD->getLexicalDeclContext();
- bool Visible = false;
- if (FromDC->containsDeclAndLoad(FromD)) {
- ToDC->addDeclInternal(ToD);
- Visible = true;
- }
- if (ToDC != ToLexicalDC && FromLexicalDC->containsDeclAndLoad(FromD)) {
- ToLexicalDC->addDeclInternal(ToD);
- Visible = true;
- }
- // If the Decl was added to any context, it was made already visible.
- // Otherwise it is still possible that it should be visible.
- if (!Visible) {
- if (auto *FromNamed = dyn_cast<NamedDecl>(FromD)) {
- auto *ToNamed = cast<NamedDecl>(ToD);
- DeclContextLookupResult FromLookup =
- FromDC->lookup(FromNamed->getDeclName());
- if (llvm::is_contained(FromLookup, FromNamed))
- ToDC->makeDeclVisibleInContext(ToNamed);
- }
- }
- }
- void updateLookupTableForTemplateParameters(TemplateParameterList &Params,
- DeclContext *OldDC) {
- ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable();
- if (!LT)
- return;
- for (NamedDecl *TP : Params)
- LT->update(TP, OldDC);
- }
- void updateLookupTableForTemplateParameters(TemplateParameterList &Params) {
- updateLookupTableForTemplateParameters(
- Params, Importer.getToContext().getTranslationUnitDecl());
- }
- 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 VisitUsingType(const UsingType *T);
- ExpectedType VisitDecltypeType(const DecltypeType *T);
- ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
- ExpectedType VisitAutoType(const AutoType *T);
- ExpectedType VisitDeducedTemplateSpecializationType(
- const DeducedTemplateSpecializationType *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
- VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *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, DeclarationName &Name, NamedDecl *&ToD,
- SourceLocation &Loc);
- 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);
- Expected<APValue> ImportAPValue(const APValue &FromValue);
- 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);
- Error ImportDefaultArgOfParmVarDecl(const ParmVarDecl *FromParam,
- ParmVarDecl *ToParam);
- Expected<InheritedConstructor>
- ImportInheritedConstructor(const InheritedConstructor &From);
- template <typename T>
- bool hasSameVisibilityContextAndLinkage(T *Found, T *From);
- bool IsStructuralMatch(Decl *From, Decl *To, bool Complain = true);
- 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 VisitBindingDecl(BindingDecl *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 VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *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 ImportUsingShadowDecls(BaseUsingDecl *D, BaseUsingDecl *ToSI);
- ExpectedDecl VisitUsingEnumDecl(UsingEnumDecl *D);
- ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
- ExpectedDecl VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
- ExpectedDecl
- VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *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 VisitSourceLocExpr(SourceLocExpr *E);
- ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
- ExpectedStmt VisitChooseExpr(ChooseExpr *E);
- ExpectedStmt VisitShuffleVectorExpr(ShuffleVectorExpr *E);
- ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
- ExpectedStmt VisitGenericSelectionExpr(GenericSelectionExpr *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 VisitFixedPointLiteral(FixedPointLiteral *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);
- ExpectedStmt VisitCXXFoldExpr(CXXFoldExpr *E);
- // Helper for chaining together multiple imports. If an error is detected,
- // subsequent imports will return default constructed nodes, so that failure
- // can be detected with a single conditional branch after a sequence of
- // imports.
- template <typename T> T importChecked(Error &Err, const T &From) {
- // Don't attempt to import nodes if we hit an error earlier.
- if (Err)
- return T{};
- Expected<T> MaybeVal = import(From);
- if (!MaybeVal) {
- Err = MaybeVal.takeError();
- return T{};
- }
- return *MaybeVal;
- }
- template<typename IIter, typename OIter>
- Error ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
- using ItemT = std::remove_reference_t<decltype(*Obegin)>;
- 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);
- }
- Error ImportOverriddenMethods(CXXMethodDecl *ToMethod,
- CXXMethodDecl *FromMethod);
- Expected<FunctionDecl *> FindFunctionTemplateSpecialization(
- FunctionDecl *FromFD);
- // Returns true if the given function has a placeholder return type and
- // that type is declared inside the body of the function.
- // E.g. auto f() { struct X{}; return X(); }
- bool hasAutoReturnTypeDeclaredInside(FunctionDecl *D);
- };
- 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(
- Importer.getToContext(), *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);
- }
- template <typename T>
- bool ASTNodeImporter::hasSameVisibilityContextAndLinkage(T *Found, T *From) {
- if (Found->getLinkageInternal() != From->getLinkageInternal())
- return false;
- 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();
- }
- template <>
- bool ASTNodeImporter::hasSameVisibilityContextAndLinkage(TypedefNameDecl *Found,
- TypedefNameDecl *From) {
- if (Found->getLinkageInternal() != From->getLinkageInternal())
- return false;
- if (From->isInAnonymousNamespace() && Found->isInAnonymousNamespace())
- return Importer.GetFromTU(Found) == From->getTranslationUnitDecl();
- return From->isInAnonymousNamespace() == Found->isInAnonymousNamespace();
- }
- } // 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 SVE_TYPE(Name, Id, SingletonId) \
- case BuiltinType::Id: \
- return Importer.getToContext().SingletonId;
- #include "clang/Basic/AArch64SVEACLETypes.def"
- #define PPC_VECTOR_TYPE(Name, Id, Size) \
- case BuiltinType::Id: \
- return Importer.getToContext().Id##Ty;
- #include "clang/Basic/PPCTypes.def"
- #define RVV_TYPE(Name, Id, SingletonId) \
- case BuiltinType::Id: \
- return Importer.getToContext().SingletonId;
- #include "clang/Basic/RISCVVTypes.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();
- ExpectedTypePtr ClassTypeOrErr = import(T->getClass());
- if (!ClassTypeOrErr)
- return ClassTypeOrErr.takeError();
- return Importer.getToContext().getMemberPointerType(*ToPointeeTypeOrErr,
- *ClassTypeOrErr);
- }
- ExpectedType
- ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
- Error Err = Error::success();
- auto ToElementType = importChecked(Err, T->getElementType());
- auto ToSizeExpr = importChecked(Err, T->getSizeExpr());
- if (Err)
- return std::move(Err);
- return Importer.getToContext().getConstantArrayType(
- ToElementType, T->getSize(), ToSizeExpr, 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) {
- Error Err = Error::success();
- QualType ToElementType = importChecked(Err, T->getElementType());
- Expr *ToSizeExpr = importChecked(Err, T->getSizeExpr());
- SourceRange ToBracketsRange = importChecked(Err, T->getBracketsRange());
- if (Err)
- return std::move(Err);
- return Importer.getToContext().getVariableArrayType(
- ToElementType, ToSizeExpr, T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers(), ToBracketsRange);
- }
- ExpectedType ASTNodeImporter::VisitDependentSizedArrayType(
- const DependentSizedArrayType *T) {
- Error Err = Error::success();
- QualType ToElementType = importChecked(Err, T->getElementType());
- Expr *ToSizeExpr = importChecked(Err, T->getSizeExpr());
- SourceRange ToBracketsRange = importChecked(Err, T->getBracketsRange());
- if (Err)
- return std::move(Err);
- // 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();
- Error Err = Error::success();
- FunctionProtoType::ExtProtoInfo ToEPI;
- 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.NoexceptExpr =
- importChecked(Err, FromEPI.ExceptionSpec.NoexceptExpr);
- ToEPI.ExceptionSpec.SourceDecl =
- importChecked(Err, FromEPI.ExceptionSpec.SourceDecl);
- ToEPI.ExceptionSpec.SourceTemplate =
- importChecked(Err, FromEPI.ExceptionSpec.SourceTemplate);
- ToEPI.ExceptionSpec.Exceptions = ExceptionTypes;
- if (Err)
- return std::move(Err);
- return Importer.getToContext().getFunctionType(
- *ToReturnTypeOrErr, ArgTypes, ToEPI);
- }
- ExpectedType ASTNodeImporter::VisitUnresolvedUsingType(
- const UnresolvedUsingType *T) {
- Error Err = Error::success();
- auto ToD = importChecked(Err, T->getDecl());
- auto ToPrevD = importChecked(Err, T->getDecl()->getPreviousDecl());
- if (Err)
- return std::move(Err);
- 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::VisitUsingType(const UsingType *T) {
- Expected<UsingShadowDecl *> FoundOrErr = import(T->getFoundDecl());
- if (!FoundOrErr)
- return FoundOrErr.takeError();
- Expected<QualType> UnderlyingOrErr = import(T->getUnderlyingType());
- if (!UnderlyingOrErr)
- return UnderlyingOrErr.takeError();
- return Importer.getToContext().getUsingType(*FoundOrErr, *UnderlyingOrErr);
- }
- 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();
- ExpectedDecl ToTypeConstraintConcept = import(T->getTypeConstraintConcept());
- if (!ToTypeConstraintConcept)
- return ToTypeConstraintConcept.takeError();
- SmallVector<TemplateArgument, 2> ToTemplateArgs;
- ArrayRef<TemplateArgument> FromTemplateArgs = T->getTypeConstraintArguments();
- if (Error Err = ImportTemplateArguments(FromTemplateArgs.data(),
- FromTemplateArgs.size(),
- ToTemplateArgs))
- return std::move(Err);
- return Importer.getToContext().getAutoType(
- *ToDeducedTypeOrErr, T->getKeyword(), /*IsDependent*/false,
- /*IsPack=*/false, cast_or_null<ConceptDecl>(*ToTypeConstraintConcept),
- ToTemplateArgs);
- }
- ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType(
- const DeducedTemplateSpecializationType *T) {
- // FIXME: Make sure that the "to" context supports C++17!
- Expected<TemplateName> ToTemplateNameOrErr = import(T->getTemplateName());
- if (!ToTemplateNameOrErr)
- return ToTemplateNameOrErr.takeError();
- ExpectedType ToDeducedTypeOrErr = import(T->getDeducedType());
- if (!ToDeducedTypeOrErr)
- return ToDeducedTypeOrErr.takeError();
- return Importer.getToContext().getDeducedTemplateSpecializationType(
- *ToTemplateNameOrErr, *ToDeducedTypeOrErr, T->isDependentType());
- }
- 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) {
- Expected<const TemplateTypeParmType *> ReplacedOrErr =
- import(T->getReplacedParameter());
- if (!ReplacedOrErr)
- return ReplacedOrErr.takeError();
- ExpectedType ToReplacementTypeOrErr = import(T->getReplacementType());
- if (!ToReplacementTypeOrErr)
- return ToReplacementTypeOrErr.takeError();
- return Importer.getToContext().getSubstTemplateTypeParmType(
- *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType());
- }
- ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
- const SubstTemplateTypeParmPackType *T) {
- Expected<const TemplateTypeParmType *> ReplacedOrErr =
- import(T->getReplacedParameter());
- if (!ReplacedOrErr)
- return ReplacedOrErr.takeError();
- Expected<TemplateArgument> ToArgumentPack = import(T->getArgumentPack());
- if (!ToArgumentPack)
- return ToArgumentPack.takeError();
- return Importer.getToContext().getSubstTemplateTypeParmPackType(
- *ReplacedOrErr, *ToArgumentPack);
- }
- 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 (!T->isCanonicalUnqualified()) {
- 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(),
- /*ExpactPack=*/false);
- }
- 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);
- // FIXME: We could support these constructs by importing a different type of
- // this parameter and by importing the original type of the parameter only
- // after the FunctionDecl is created. See
- // VisitFunctionDecl::UsedDifferentProtoType.
- 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::ImportDeclParts(NamedDecl *D, DeclarationName &Name,
- NamedDecl *&ToD, SourceLocation &Loc) {
- // 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();
- }
- // We use strict error handling in case of records and enums, but not
- // with e.g. namespaces.
- //
- // FIXME Clients of the ASTImporter should be able to choose an
- // appropriate error handling strategy for their needs. For instance,
- // they may not want to mark an entire namespace as erroneous merely
- // because there is an ODR error with two typedefs. As another example,
- // the client may allow EnumConstantDecls with same names but with
- // different values in two distinct translation units.
- bool AccumulateChildErrors = isa<TagDecl>(FromDC);
- Error ChildErrors = Error::success();
- for (auto *From : FromDC->decls()) {
- ExpectedDecl ImportedOrErr = import(From);
- // If we are in the process of ImportDefinition(...) for a RecordDecl we
- // want to make sure that we are also completing each FieldDecl. There
- // are currently cases where this does not happen and this is correctness
- // fix since operations such as code generation will expect this to be so.
- if (ImportedOrErr) {
- FieldDecl *FieldFrom = dyn_cast_or_null<FieldDecl>(From);
- Decl *ImportedDecl = *ImportedOrErr;
- FieldDecl *FieldTo = dyn_cast_or_null<FieldDecl>(ImportedDecl);
- if (FieldFrom && FieldTo) {
- RecordDecl *FromRecordDecl = nullptr;
- RecordDecl *ToRecordDecl = nullptr;
- // If we have a field that is an ArrayType we need to check if the array
- // element is a RecordDecl and if so we need to import the definition.
- if (FieldFrom->getType()->isArrayType()) {
- // getBaseElementTypeUnsafe(...) handles multi-dimensonal arrays for us.
- FromRecordDecl = FieldFrom->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl();
- ToRecordDecl = FieldTo->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl();
- }
- if (!FromRecordDecl || !ToRecordDecl) {
- const RecordType *RecordFrom =
- FieldFrom->getType()->getAs<RecordType>();
- const RecordType *RecordTo = FieldTo->getType()->getAs<RecordType>();
- if (RecordFrom && RecordTo) {
- FromRecordDecl = RecordFrom->getDecl();
- ToRecordDecl = RecordTo->getDecl();
- }
- }
- if (FromRecordDecl && ToRecordDecl) {
- if (FromRecordDecl->isCompleteDefinition() &&
- !ToRecordDecl->isCompleteDefinition()) {
- Error Err = ImportDefinition(FromRecordDecl, ToRecordDecl);
- if (Err && AccumulateChildErrors)
- ChildErrors = joinErrors(std::move(ChildErrors), std::move(Err));
- else
- consumeError(std::move(Err));
- }
- }
- }
- } else {
- if (AccumulateChildErrors)
- ChildErrors =
- joinErrors(std::move(ChildErrors), ImportedOrErr.takeError());
- else
- consumeError(ImportedOrErr.takeError());
- }
- }
- // We reorder declarations in RecordDecls because they may have another order
- // in the "to" context than they have in the "from" context. This may happen
- // e.g when we import a class like this:
- // struct declToImport {
- // int a = c + b;
- // int b = 1;
- // int c = 2;
- // };
- // During the import of `a` we import first the dependencies in sequence,
- // thus the order would be `c`, `b`, `a`. We will get the normal order by
- // first removing the already imported members and then adding them in the
- // order as they apper in the "from" context.
- //
- // Keeping field order is vital because it determines structure layout.
- //
- // Here and below, we cannot call field_begin() method and its callers on
- // ToDC if it has an external storage. Calling field_begin() will
- // automatically load all the fields by calling
- // LoadFieldsFromExternalStorage(). LoadFieldsFromExternalStorage() would
- // call ASTImporter::Import(). This is because the ExternalASTSource
- // interface in LLDB is implemented by the means of the ASTImporter. However,
- // calling an import at this point would result in an uncontrolled import, we
- // must avoid that.
- const auto *FromRD = dyn_cast<RecordDecl>(FromDC);
- if (!FromRD)
- return ChildErrors;
- auto ToDCOrErr = Importer.ImportContext(FromDC);
- if (!ToDCOrErr) {
- consumeError(std::move(ChildErrors));
- return ToDCOrErr.takeError();
- }
- DeclContext *ToDC = *ToDCOrErr;
- // Remove all declarations, which may be in wrong order in the
- // lexical DeclContext and then add them in the proper order.
- for (auto *D : FromRD->decls()) {
- if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<FriendDecl>(D)) {
- assert(D && "DC contains a null decl");
- Decl *ToD = Importer.GetAlreadyImportedOrNull(D);
- // Remove only the decls which we successfully imported.
- if (ToD) {
- assert(ToDC == ToD->getLexicalDeclContext() && ToDC->containsDecl(ToD));
- // Remove the decl from its wrong place in the linked list.
- ToDC->removeDecl(ToD);
- // Add the decl to the end of the linked list.
- // This time it will be at the proper place because the enclosing for
- // loop iterates in the original (good) order of the decls.
- ToDC->addDeclInternal(ToD);
- }
- }
- }
- return ChildErrors;
- }
- 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) {
- auto DefinitionCompleter = [To]() {
- // There are cases in LLDB when we first import a class without its
- // members. The class will have DefinitionData, but no members. Then,
- // importDefinition is called from LLDB, which tries to get the members, so
- // when we get here, the class already has the DefinitionData set, so we
- // must unset the CompleteDefinition here to be able to complete again the
- // definition.
- To->setCompleteDefinition(false);
- To->completeDefinition();
- };
- if (To->getDefinition() || To->isBeingDefined()) {
- if (Kind == IDK_Everything ||
- // In case of lambdas, the class already has a definition ptr set, but
- // the contained decls are not imported yet. Also, isBeingDefined was
- // set in CXXRecordDecl::CreateLambda. We must import the contained
- // decls here and finish the definition.
- (To->isLambda() && shouldForceImportDeclContext(Kind))) {
- if (To->isLambda()) {
- auto *FromCXXRD = cast<CXXRecordDecl>(From);
- SmallVector<LambdaCapture, 8> ToCaptures;
- ToCaptures.reserve(FromCXXRD->capture_size());
- for (const auto &FromCapture : FromCXXRD->captures()) {
- if (auto ToCaptureOrErr = import(FromCapture))
- ToCaptures.push_back(*ToCaptureOrErr);
- else
- return ToCaptureOrErr.takeError();
- }
- cast<CXXRecordDecl>(To)->setCaptures(Importer.getToContext(),
- ToCaptures);
- }
- Error Result = ImportDeclContext(From, /*ForceImport=*/true);
- // Finish the definition of the lambda, set isBeingDefined to false.
- if (To->isLambda())
- DefinitionCompleter();
- return Result;
- }
- return Error::success();
- }
- To->startDefinition();
- // Complete the definition even if error is returned.
- // The RecordDecl may be already part of the AST so it is better to
- // have it in complete state even if something is wrong with it.
- auto DefinitionCompleterScopeExit =
- llvm::make_scope_exit(DefinitionCompleter);
- 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();
- #define FIELD(Name, Width, Merge) \
- ToData.Name = FromData.Name;
- #include "clang/AST/CXXRecordDeclDefinitionBits.def"
- // 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;
- 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 (EvaluatedStmt *FromEval = From->getEvaluatedStmt()) {
- EvaluatedStmt *ToEval = To->ensureEvaluatedStmt();
- ToEval->HasConstantInitialization = FromEval->HasConstantInitialization;
- ToEval->HasConstantDestruction = FromEval->HasConstantDestruction;
- // FIXME: Also import the initializer value.
- }
- // 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) {
- // Eliminate a potential failure point where we attempt to re-import
- // something we're trying to import while completing ToRecord.
- Decl *ToOrigin = Importer.GetOriginalDecl(To);
- if (ToOrigin) {
- To = ToOrigin;
- }
- StructuralEquivalenceContext Ctx(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
- false, Complain);
- 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::VisitBindingDecl(BindingDecl *D) {
- DeclContext *DC, *LexicalDC;
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToND;
- if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToND, Loc))
- return std::move(Err);
- if (ToND)
- return ToND;
- BindingDecl *ToD;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo()))
- return ToD;
- Error Err = Error::success();
- QualType ToType = importChecked(Err, D->getType());
- Expr *ToBinding = importChecked(Err, D->getBinding());
- ValueDecl *ToDecomposedDecl = importChecked(Err, D->getDecomposedDecl());
- if (Err)
- return std::move(Err);
- ToD->setBinding(ToType, ToBinding);
- ToD->setDecomposedDecl(ToDecomposedDecl);
- addDeclToContexts(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;
- Error Err = Error::success();
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToRParenLoc = importChecked(Err, D->getRParenLoc());
- auto ToAssertExpr = importChecked(Err, D->getAssertExpr());
- auto ToMessage = importChecked(Err, D->getMessage());
- if (Err)
- return std::move(Err);
- 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()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, Decl::IDNS_Namespace, ConflictingDecls.data(),
- ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc RBraceLocOrErr = import(D->getRBraceLoc());
- if (!RBraceLocOrErr)
- return RBraceLocOrErr.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->setRBraceLoc(*RBraceLocOrErr);
- 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.
- Error Err = Error::success();
- auto ToNamespaceLoc = importChecked(Err, D->getNamespaceLoc());
- auto ToAliasLoc = importChecked(Err, D->getAliasLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto ToTargetNameLoc = importChecked(Err, D->getTargetNameLoc());
- auto ToNamespace = importChecked(Err, D->getNamespace());
- if (Err)
- return std::move(Err);
- 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.
- DeclarationName Name;
- SourceLocation Loc;
- NamedDecl *ToD;
- // Do not import the DeclContext, we will import it once the TypedefNameDecl
- // is created.
- if (Error Err = ImportDeclParts(D, Name, ToD, Loc))
- return std::move(Err);
- if (ToD)
- return ToD;
- DeclContext *DC = cast_or_null<DeclContext>(
- Importer.GetAlreadyImportedOrNull(cast<Decl>(D->getDeclContext())));
- DeclContext *LexicalDC =
- cast_or_null<DeclContext>(Importer.GetAlreadyImportedOrNull(
- cast<Decl>(D->getLexicalDeclContext())));
- // 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).
- // Note: Repeated typedefs are not valid in C99:
- // 'typedef int T; typedef int T;' is invalid
- // We do not care about this now.
- if (DC && !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)) {
- if (!hasSameVisibilityContextAndLinkage(FoundTypedef, D))
- continue;
- 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.
- } else {
- ConflictingDecls.push_back(FoundDecl);
- }
- }
- }
- if (!ConflictingDecls.empty()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- Error Err = Error::success();
- auto ToUnderlyingType = importChecked(Err, D->getUnderlyingType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToBeginLoc = importChecked(Err, D->getBeginLoc());
- if (Err)
- return std::move(Err);
- // Create the new typedef node.
- // FIXME: ToUnderlyingType is not used.
- (void)ToUnderlyingType;
- 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;
- // Import the DeclContext and set it to the Typedef.
- if ((Err = ImportDeclContext(D, DC, LexicalDC)))
- return std::move(Err);
- ToTypedef->setDeclContext(DC);
- ToTypedef->setLexicalDeclContext(LexicalDC);
- // Add to the lookupTable because we could not do that in MapImported.
- Importer.AddToLookupTable(ToTypedef);
- ToTypedef->setAccess(D->getAccess());
- // 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()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- Error Err = Error::success();
- auto ToTemplateParameters = importChecked(Err, D->getTemplateParameters());
- auto ToTemplatedDecl = importChecked(Err, D->getTemplatedDecl());
- if (Err)
- return std::move(Err);
- 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);
- if (DC != Importer.getToContext().getTranslationUnitDecl())
- updateLookupTableForTemplateParameters(*ToTemplateParameters);
- 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.
- EnumDecl *PrevDecl = nullptr;
- 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 (!hasSameVisibilityContextAndLinkage(FoundEnum, D))
- continue;
- if (IsStructuralMatch(D, FoundEnum)) {
- EnumDecl *FoundDef = FoundEnum->getDefinition();
- if (D->isThisDeclarationADefinition() && FoundDef)
- return Importer.MapImported(D, FoundDef);
- PrevDecl = FoundEnum->getMostRecentDecl();
- break;
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- }
- if (!ConflictingDecls.empty()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- SearchName, DC, IDNS, ConflictingDecls.data(),
- ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- Error Err = Error::success();
- auto ToBeginLoc = importChecked(Err, D->getBeginLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto ToIntegerType = importChecked(Err, D->getIntegerType());
- auto ToBraceRange = importChecked(Err, D->getBraceRange());
- if (Err)
- return std::move(Err);
- // Create the enum declaration.
- EnumDecl *D2;
- if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), DC, ToBeginLoc,
- Loc, Name.getAsIdentifierInfo(), PrevDecl, D->isScoped(),
- D->isScopedUsingClassTag(), D->isFixed()))
- return D2;
- D2->setQualifierInfo(ToQualifierLoc);
- D2->setIntegerType(ToIntegerType);
- D2->setBraceRange(ToBraceRange);
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- addDeclToContexts(D, D2);
- if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {
- TemplateSpecializationKind SK = MemberInfo->getTemplateSpecializationKind();
- EnumDecl *FromInst = D->getInstantiatedFromMemberEnum();
- if (Expected<EnumDecl *> ToInstOrErr = import(FromInst))
- D2->setInstantiationOfMemberEnum(*ToInstOrErr, SK);
- else
- return ToInstOrErr.takeError();
- if (ExpectedSLoc POIOrErr = import(MemberInfo->getPointOfInstantiation()))
- D2->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
- // 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 = nullptr, *LexicalDC = nullptr;
- 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;
- // 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() && !D->isLambda()) {
- 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 (!hasSameVisibilityContextAndLinkage(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);
- } // kind is RecordDecl
- } // for
- if (!ConflictingDecls.empty() && SearchName) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- SearchName, DC, IDNS, ConflictingDecls.data(),
- ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- 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,
- DCXX->hasKnownLambdaInternalLinkage());
- D2CXX->setDeviceLambdaManglingNumber(
- DCXX->getDeviceLambdaManglingNumber());
- } 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);
- addDeclToContexts(D, 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);
- addDeclToContexts(D, D2);
- }
- if (auto BraceRangeOrErr = import(D->getBraceRange()))
- D2->setBraceRange(*BraceRangeOrErr);
- else
- return BraceRangeOrErr.takeError();
- 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()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- 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();
- }
- // Returns true if the given D has a DeclContext up to the TranslationUnitDecl
- // which is equal to the given DC.
- static bool isAncestorDeclContextOf(const DeclContext *DC, const Decl *D) {
- const DeclContext *DCi = D->getDeclContext();
- while (DCi != D->getTranslationUnitDecl()) {
- if (DCi == DC)
- return true;
- DCi = DCi->getParent();
- }
- return false;
- }
- bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
- QualType FromTy = D->getType();
- const auto *FromFPT = FromTy->getAs<FunctionProtoType>();
- assert(FromFPT && "Must be called on FunctionProtoType");
- if (const AutoType *AutoT =
- FromFPT->getReturnType()->getContainedAutoType()) {
- QualType DeducedT = AutoT->getDeducedType();
- if (const auto *RecordT =
- !DeducedT.isNull() ? DeducedT->getAs<RecordType>() : nullptr) {
- const RecordDecl *RD = RecordT->getDecl();
- assert(RD);
- if (isAncestorDeclContextOf(D, RD)) {
- assert(RD->getLexicalDeclContext() == RD->getDeclContext());
- return true;
- }
- }
- }
- if (const auto *TypedefT = FromFPT->getReturnType()->getAs<TypedefType>()) {
- const TypedefNameDecl *TD = TypedefT->getDecl();
- assert(TD);
- if (isAncestorDeclContextOf(D, TD)) {
- assert(TD->getLexicalDeclContext() == TD->getDeclContext());
- return true;
- }
- }
- return false;
- }
- ExplicitSpecifier
- ASTNodeImporter::importExplicitSpecifier(Error &Err, ExplicitSpecifier ESpec) {
- Expr *ExplicitExpr = ESpec.getExpr();
- if (ExplicitExpr)
- ExplicitExpr = importChecked(Err, ESpec.getExpr());
- return ExplicitSpecifier(ExplicitExpr, ESpec.getKind());
- }
- 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 (!hasSameVisibilityContextAndLinkage(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()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- // 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()) {
- if (FunctionTemplateDecl *DescribedD =
- D->getDescribedFunctionTemplate()) {
- // Handle a "templated" function together with its described
- // template. This avoids need for a similar check at import of the
- // described template.
- assert(FoundByLookup->getDescribedFunctionTemplate() &&
- "Templated function mapped to non-templated?");
- Importer.MapImported(DescribedD,
- FoundByLookup->getDescribedFunctionTemplate());
- }
- 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();
- TypeSourceInfo *FromTSI = D->getTypeSourceInfo();
- // Set to true if we do not import the type of the function as is. There are
- // cases when the original type would result in an infinite recursion during
- // the import. To avoid an infinite recursion when importing, we create the
- // FunctionDecl with a simplified function type and update it only after the
- // relevant AST nodes are already imported.
- // The type is related to TypeSourceInfo (it references the type), so we must
- // do the same with TypeSourceInfo.
- bool UsedDifferentProtoType = false;
- if (const auto *FromFPT = FromTy->getAs<FunctionProtoType>()) {
- QualType FromReturnTy = FromFPT->getReturnType();
- // Functions with auto return type may define a struct inside their body
- // and the return type could refer to that struct.
- // E.g.: auto foo() { struct X{}; return X(); }
- // To avoid an infinite recursion when importing, create the FunctionDecl
- // with a simplified return type.
- if (hasAutoReturnTypeDeclaredInside(D)) {
- FromReturnTy = Importer.getFromContext().VoidTy;
- UsedDifferentProtoType = true;
- }
- 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.
- if (FromEPI.ExceptionSpec.SourceDecl ||
- FromEPI.ExceptionSpec.SourceTemplate ||
- FromEPI.ExceptionSpec.NoexceptExpr) {
- FunctionProtoType::ExtProtoInfo DefaultEPI;
- FromEPI = DefaultEPI;
- UsedDifferentProtoType = true;
- }
- FromTy = Importer.getFromContext().getFunctionType(
- FromReturnTy, FromFPT->getParamTypes(), FromEPI);
- FromTSI = Importer.getFromContext().getTrivialTypeSourceInfo(
- FromTy, D->getBeginLoc());
- }
- Error Err = Error::success();
- auto T = importChecked(Err, FromTy);
- auto TInfo = importChecked(Err, FromTSI);
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- auto ToEndLoc = importChecked(Err, D->getEndLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto TrailingRequiresClause =
- importChecked(Err, D->getTrailingRequiresClause());
- if (Err)
- return std::move(Err);
- // 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)) {
- ExplicitSpecifier ESpec =
- importExplicitSpecifier(Err, FromConstructor->getExplicitSpecifier());
- if (Err)
- return std::move(Err);
- auto ToInheritedConstructor = InheritedConstructor();
- if (FromConstructor->isInheritingConstructor()) {
- Expected<InheritedConstructor> ImportedInheritedCtor =
- import(FromConstructor->getInheritedConstructor());
- if (!ImportedInheritedCtor)
- return ImportedInheritedCtor.takeError();
- ToInheritedConstructor = *ImportedInheritedCtor;
- }
- if (GetImportedOrCreateDecl<CXXConstructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, ESpec, D->UsesFPIntrin(),
- D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
- ToInheritedConstructor, TrailingRequiresClause))
- return ToFunction;
- } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
- Error Err = Error::success();
- auto ToOperatorDelete = importChecked(
- Err, const_cast<FunctionDecl *>(FromDtor->getOperatorDelete()));
- auto ToThisArg = importChecked(Err, FromDtor->getOperatorDeleteThisArg());
- if (Err)
- return std::move(Err);
- if (GetImportedOrCreateDecl<CXXDestructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
- D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind(),
- TrailingRequiresClause))
- return ToFunction;
- CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
- ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg);
- } else if (CXXConversionDecl *FromConversion =
- dyn_cast<CXXConversionDecl>(D)) {
- ExplicitSpecifier ESpec =
- importExplicitSpecifier(Err, FromConversion->getExplicitSpecifier());
- if (Err)
- return std::move(Err);
- if (GetImportedOrCreateDecl<CXXConversionDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo, D->UsesFPIntrin(),
- D->isInlineSpecified(), ESpec, D->getConstexprKind(),
- SourceLocation(), TrailingRequiresClause))
- 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->UsesFPIntrin(), Method->isInlineSpecified(),
- D->getConstexprKind(), SourceLocation(), TrailingRequiresClause))
- return ToFunction;
- } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
- ExplicitSpecifier ESpec =
- importExplicitSpecifier(Err, Guide->getExplicitSpecifier());
- CXXConstructorDecl *Ctor =
- importChecked(Err, Guide->getCorrespondingConstructor());
- if (Err)
- return std::move(Err);
- if (GetImportedOrCreateDecl<CXXDeductionGuideDecl>(
- ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, ESpec,
- NameInfo, T, TInfo, ToEndLoc, Ctor))
- return ToFunction;
- cast<CXXDeductionGuideDecl>(ToFunction)
- ->setIsCopyDeductionCandidate(Guide->isCopyDeductionCandidate());
- } else {
- if (GetImportedOrCreateDecl(
- ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart,
- NameInfo, T, TInfo, D->getStorageClass(), D->UsesFPIntrin(),
- D->isInlineSpecified(), D->hasWrittenPrototype(),
- D->getConstexprKind(), TrailingRequiresClause))
- 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.
- }
- ToFunction->setQualifierInfo(ToQualifierLoc);
- ToFunction->setAccess(D->getAccess());
- ToFunction->setLexicalDeclContext(LexicalDC);
- ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
- ToFunction->setTrivial(D->isTrivial());
- ToFunction->setPure(D->isPure());
- ToFunction->setDefaulted(D->isDefaulted());
- ToFunction->setExplicitlyDefaulted(D->isExplicitlyDefaulted());
- ToFunction->setDeletedAsWritten(D->isDeletedAsWritten());
- ToFunction->setRangeEnd(ToEndLoc);
- // Set the parameters.
- for (auto *Param : Parameters) {
- Param->setOwningFunction(ToFunction);
- ToFunction->addDeclInternal(Param);
- if (ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable())
- LT->update(Param, Importer.getToContext().getTranslationUnitDecl());
- }
- 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]);
- }
- }
- // Import the describing template function, if any.
- if (FromFT) {
- auto ToFTOrErr = import(FromFT);
- if (!ToFTOrErr)
- return ToFTOrErr.takeError();
- }
- // 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);
- }
- }
- if (D->doesThisDeclarationHaveABody()) {
- Error Err = ImportFunctionDeclBody(D, ToFunction);
- if (Err)
- return std::move(Err);
- }
- // Import and set the original type in case we used another type.
- if (UsedDifferentProtoType) {
- if (ExpectedType TyOrErr = import(D->getType()))
- ToFunction->setType(*TyOrErr);
- else
- return TyOrErr.takeError();
- if (Expected<TypeSourceInfo *> TSIOrErr = import(D->getTypeSourceInfo()))
- ToFunction->setTypeSourceInfo(*TSIOrErr);
- else
- return TSIOrErr.takeError();
- }
- // FIXME: Other bits to merge?
- // If it is a template, import all related things.
- if (Error Err = ImportTemplateInformation(D, ToFunction))
- return std::move(Err);
- addDeclToContexts(D, ToFunction);
- if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
- if (Error Err = ImportOverriddenMethods(cast<CXXMethodDecl>(ToFunction),
- FromCXXMethod))
- return std::move(Err);
- // 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::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
- return VisitFunctionDecl(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);
- }
- }
- Error Err = Error::success();
- auto ToType = importChecked(Err, D->getType());
- auto ToTInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToBitWidth = importChecked(Err, D->getBitWidth());
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- auto ToInitializer = importChecked(Err, D->getInClassInitializer());
- if (Err)
- return std::move(Err);
- const Type *ToCapturedVLAType = nullptr;
- if (Error Err = Importer.importInto(
- ToCapturedVLAType, cast_or_null<Type>(D->getCapturedVLAType())))
- return std::move(Err);
- 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());
- if (ToCapturedVLAType)
- ToField->setCapturedVLAType(cast<VariableArrayType>(ToCapturedVLAType));
- 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;
- }
- /// Used as return type of getFriendCountAndPosition.
- struct FriendCountAndPosition {
- /// Number of similar looking friends.
- unsigned int TotalCount;
- /// Index of the specific FriendDecl.
- unsigned int IndexOfDecl;
- };
- template <class T>
- static FriendCountAndPosition getFriendCountAndPosition(
- const FriendDecl *FD,
- llvm::function_ref<T(const FriendDecl *)> GetCanTypeOrDecl) {
- unsigned int FriendCount = 0;
- llvm::Optional<unsigned int> FriendPosition;
- const auto *RD = cast<CXXRecordDecl>(FD->getLexicalDeclContext());
- T TypeOrDecl = GetCanTypeOrDecl(FD);
- for (const FriendDecl *FoundFriend : RD->friends()) {
- if (FoundFriend == FD) {
- FriendPosition = FriendCount;
- ++FriendCount;
- } else if (!FoundFriend->getFriendDecl() == !FD->getFriendDecl() &&
- GetCanTypeOrDecl(FoundFriend) == TypeOrDecl) {
- ++FriendCount;
- }
- }
- assert(FriendPosition && "Friend decl not found in own parent.");
- return {FriendCount, *FriendPosition};
- }
- static FriendCountAndPosition getFriendCountAndPosition(const FriendDecl *FD) {
- if (FD->getFriendType())
- return getFriendCountAndPosition<QualType>(FD, [](const FriendDecl *F) {
- if (TypeSourceInfo *TSI = F->getFriendType())
- return TSI->getType().getCanonicalType();
- llvm_unreachable("Wrong friend object type.");
- });
- else
- return getFriendCountAndPosition<Decl *>(FD, [](const FriendDecl *F) {
- if (Decl *D = F->getFriendDecl())
- return D->getCanonicalDecl();
- llvm_unreachable("Wrong friend object type.");
- });
- }
- 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.
- // We try to maintain order and count of redundant friend declarations.
- const auto *RD = cast<CXXRecordDecl>(DC);
- FriendDecl *ImportedFriend = RD->getFirstFriend();
- SmallVector<FriendDecl *, 2> ImportedEquivalentFriends;
- while (ImportedFriend) {
- bool Match = false;
- if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
- Match =
- IsStructuralMatch(D->getFriendDecl(), ImportedFriend->getFriendDecl(),
- /*Complain=*/false);
- } else if (D->getFriendType() && ImportedFriend->getFriendType()) {
- Match = Importer.IsStructurallyEquivalent(
- D->getFriendType()->getType(),
- ImportedFriend->getFriendType()->getType(), /*Complain=*/false);
- }
- if (Match)
- ImportedEquivalentFriends.push_back(ImportedFriend);
- ImportedFriend = ImportedFriend->getNextFriend();
- }
- FriendCountAndPosition CountAndPosition = getFriendCountAndPosition(D);
- assert(ImportedEquivalentFriends.size() <= CountAndPosition.TotalCount &&
- "Class with non-matching friends is imported, ODR check wrong?");
- if (ImportedEquivalentFriends.size() == CountAndPosition.TotalCount)
- return Importer.MapImported(
- D, ImportedEquivalentFriends[CountAndPosition.IndexOfDecl]);
- // Not found. Create it.
- // The declarations will be put into order later by ImportDeclContext.
- 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);
- }
- }
- Error Err = Error::success();
- auto ToType = importChecked(Err, D->getType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToBitWidth = importChecked(Err, D->getBitWidth());
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- if (Err)
- return std::move(Err);
- 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 (!hasSameVisibilityContextAndLinkage(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()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, IDNS, ConflictingDecls.data(), ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- Error Err = Error::success();
- auto ToType = importChecked(Err, D->getType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- if (Err)
- return std::move(Err);
- VarDecl *ToVar;
- if (auto *FromDecomp = dyn_cast<DecompositionDecl>(D)) {
- SmallVector<BindingDecl *> Bindings(FromDecomp->bindings().size());
- if (Error Err =
- ImportArrayChecked(FromDecomp->bindings(), Bindings.begin()))
- return std::move(Err);
- DecompositionDecl *ToDecomp;
- if (GetImportedOrCreateDecl(
- ToDecomp, FromDecomp, Importer.getToContext(), DC, ToInnerLocStart,
- Loc, ToType, ToTypeSourceInfo, D->getStorageClass(), Bindings))
- return ToDecomp;
- ToVar = ToDecomp;
- } else {
- // Create the imported variable.
- if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
- ToInnerLocStart, Loc,
- Name.getAsIdentifierInfo(), ToType,
- ToTypeSourceInfo, D->getStorageClass()))
- return ToVar;
- }
- ToVar->setTSCSpec(D->getTSCSpec());
- ToVar->setQualifierInfo(ToQualifierLoc);
- ToVar->setAccess(D->getAccess());
- ToVar->setLexicalDeclContext(LexicalDC);
- if (FoundByLookup) {
- auto *Recent = const_cast<VarDecl *>(FoundByLookup->getMostRecentDecl());
- ToVar->setPreviousDecl(Recent);
- }
- // Import the described template, if any.
- if (D->getDescribedVarTemplate()) {
- auto ToVTOrErr = import(D->getDescribedVarTemplate());
- if (!ToVTOrErr)
- return ToVTOrErr.takeError();
- }
- if (Error Err = ImportInitializer(D, ToVar))
- return std::move(Err);
- if (D->isConstexpr())
- ToVar->setConstexpr(true);
- addDeclToContexts(D, 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();
- Error Err = Error::success();
- auto ToDeclName = importChecked(Err, D->getDeclName());
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToType = importChecked(Err, D->getType());
- if (Err)
- return std::move(Err);
- // Create the imported parameter.
- ImplicitParamDecl *ToParm = nullptr;
- if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
- ToLocation, ToDeclName.getAsIdentifierInfo(),
- ToType, D->getParameterKind()))
- return ToParm;
- return ToParm;
- }
- Error ASTNodeImporter::ImportDefaultArgOfParmVarDecl(
- const ParmVarDecl *FromParam, ParmVarDecl *ToParam) {
- ToParam->setHasInheritedDefaultArg(FromParam->hasInheritedDefaultArg());
- ToParam->setKNRPromoted(FromParam->isKNRPromoted());
- if (FromParam->hasUninstantiatedDefaultArg()) {
- if (auto ToDefArgOrErr = import(FromParam->getUninstantiatedDefaultArg()))
- ToParam->setUninstantiatedDefaultArg(*ToDefArgOrErr);
- else
- return ToDefArgOrErr.takeError();
- } else if (FromParam->hasUnparsedDefaultArg()) {
- ToParam->setUnparsedDefaultArg();
- } else if (FromParam->hasDefaultArg()) {
- if (auto ToDefArgOrErr = import(FromParam->getDefaultArg()))
- ToParam->setDefaultArg(*ToDefArgOrErr);
- else
- return ToDefArgOrErr.takeError();
- }
- return Error::success();
- }
- Expected<InheritedConstructor>
- ASTNodeImporter::ImportInheritedConstructor(const InheritedConstructor &From) {
- Error Err = Error::success();
- CXXConstructorDecl *ToBaseCtor = importChecked(Err, From.getConstructor());
- ConstructorUsingShadowDecl *ToShadow =
- importChecked(Err, From.getShadowDecl());
- if (Err)
- return std::move(Err);
- return InheritedConstructor(ToShadow, ToBaseCtor);
- }
- 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();
- Error Err = Error::success();
- auto ToDeclName = importChecked(Err, D->getDeclName());
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- auto ToType = importChecked(Err, D->getType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- if (Err)
- return std::move(Err);
- 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. It should be no problem if it was already done.
- // Do not import the default expression before GetImportedOrCreateDecl call
- // to avoid possible infinite import loop because circular dependency.
- if (Error Err = ImportDefaultArgOfParmVarDecl(D, ToParm))
- return std::move(Err);
- 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);
- }
- }
- Error Err = Error::success();
- auto ToEndLoc = importChecked(Err, D->getEndLoc());
- auto ToReturnType = importChecked(Err, D->getReturnType());
- auto ToReturnTypeSourceInfo =
- importChecked(Err, D->getReturnTypeSourceInfo());
- if (Err)
- return std::move(Err);
- ObjCMethodDecl *ToMethod;
- if (GetImportedOrCreateDecl(
- ToMethod, D, Importer.getToContext(), Loc, ToEndLoc,
- Name.getObjCSelector(), ToReturnType, ToReturnTypeSourceInfo, DC,
- D->isInstanceMethod(), D->isVariadic(), D->isPropertyAccessor(),
- D->isSynthesizedAccessorStub(), 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);
- // Implicit params are declared when Sema encounters the definition but this
- // never happens when the method is imported. Manually declare the implicit
- // params now that the MethodDecl knows its class interface.
- if (D->getSelfDecl())
- ToMethod->createImplicitParams(Importer.getToContext(),
- ToMethod->getClassInterface());
- 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;
- Error Err = Error::success();
- auto ToVarianceLoc = importChecked(Err, D->getVarianceLoc());
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToColonLoc = importChecked(Err, D->getColonLoc());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToAtStartLoc = importChecked(Err, D->getAtStartLoc());
- auto ToCategoryNameLoc = importChecked(Err, D->getCategoryNameLoc());
- auto ToIvarLBraceLoc = importChecked(Err, D->getIvarLBraceLoc());
- auto ToIvarRBraceLoc = importChecked(Err, D->getIvarRBraceLoc());
- if (Err)
- return std::move(Err);
- 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::ImportUsingShadowDecls(BaseUsingDecl *D,
- BaseUsingDecl *ToSI) {
- for (UsingShadowDecl *FromShadow : D->shadows()) {
- if (Expected<UsingShadowDecl *> ToShadowOrErr = import(FromShadow))
- ToSI->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 ToSI;
- }
- 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;
- Error Err = Error::success();
- auto ToLoc = importChecked(Err, D->getNameInfo().getLoc());
- auto ToUsingLoc = importChecked(Err, D->getUsingLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- if (Err)
- return std::move(Err);
- 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();
- }
- return ImportUsingShadowDecls(D, ToUsing);
- }
- ExpectedDecl ASTNodeImporter::VisitUsingEnumDecl(UsingEnumDecl *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;
- Error Err = Error::success();
- auto ToUsingLoc = importChecked(Err, D->getUsingLoc());
- auto ToEnumLoc = importChecked(Err, D->getEnumLoc());
- auto ToEnumDecl = importChecked(Err, D->getEnumDecl());
- if (Err)
- return std::move(Err);
- UsingEnumDecl *ToUsingEnum;
- if (GetImportedOrCreateDecl(ToUsingEnum, D, Importer.getToContext(), DC,
- ToUsingLoc, ToEnumLoc, Loc, ToEnumDecl))
- return ToUsingEnum;
- ToUsingEnum->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToUsingEnum);
- if (UsingEnumDecl *FromPattern =
- Importer.getFromContext().getInstantiatedFromUsingEnumDecl(D)) {
- if (Expected<UsingEnumDecl *> ToPatternOrErr = import(FromPattern))
- Importer.getToContext().setInstantiatedFromUsingEnumDecl(ToUsingEnum,
- *ToPatternOrErr);
- else
- return ToPatternOrErr.takeError();
- }
- return ImportUsingShadowDecls(D, ToUsingEnum);
- }
- 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<BaseUsingDecl *> ToIntroducerOrErr = import(D->getIntroducer());
- if (!ToIntroducerOrErr)
- return ToIntroducerOrErr.takeError();
- Expected<NamedDecl *> ToTargetOrErr = import(D->getTargetDecl());
- if (!ToTargetOrErr)
- return ToTargetOrErr.takeError();
- UsingShadowDecl *ToShadow;
- if (auto *FromConstructorUsingShadow =
- dyn_cast<ConstructorUsingShadowDecl>(D)) {
- Error Err = Error::success();
- ConstructorUsingShadowDecl *Nominated = importChecked(
- Err, FromConstructorUsingShadow->getNominatedBaseClassShadowDecl());
- if (Err)
- return std::move(Err);
- // The 'Target' parameter of ConstructorUsingShadowDecl constructor
- // is really the "NominatedBaseClassShadowDecl" value if it exists
- // (see code of ConstructorUsingShadowDecl::ConstructorUsingShadowDecl).
- // We should pass the NominatedBaseClassShadowDecl to it (if non-null) to
- // get the correct values.
- if (GetImportedOrCreateDecl<ConstructorUsingShadowDecl>(
- ToShadow, D, Importer.getToContext(), DC, Loc,
- cast<UsingDecl>(*ToIntroducerOrErr),
- Nominated ? Nominated : *ToTargetOrErr,
- FromConstructorUsingShadow->constructsVirtualBase()))
- return ToShadow;
- } else {
- if (GetImportedOrCreateDecl(ToShadow, D, Importer.getToContext(), DC, Loc,
- Name, *ToIntroducerOrErr, *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();
- Error Err = Error::success();
- auto ToNominatedNamespace = importChecked(Err, D->getNominatedNamespace());
- auto ToUsingLoc = importChecked(Err, D->getUsingLoc());
- auto ToNamespaceKeyLocation =
- importChecked(Err, D->getNamespaceKeyLocation());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto ToIdentLocation = importChecked(Err, D->getIdentLocation());
- if (Err)
- return std::move(Err);
- 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;
- Error Err = Error::success();
- auto ToLoc = importChecked(Err, D->getNameInfo().getLoc());
- auto ToUsingLoc = importChecked(Err, D->getUsingLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto ToEllipsisLoc = importChecked(Err, D->getEllipsisLoc());
- if (Err)
- return std::move(Err);
- 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;
- Error Err = Error::success();
- auto ToUsingLoc = importChecked(Err, D->getUsingLoc());
- auto ToTypenameLoc = importChecked(Err, D->getTypenameLoc());
- auto ToQualifierLoc = importChecked(Err, D->getQualifierLoc());
- auto ToEllipsisLoc = importChecked(Err, D->getEllipsisLoc());
- if (Err)
- return std::move(Err);
- 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;
- }
- ExpectedDecl ASTNodeImporter::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
- Decl* ToD = nullptr;
- switch (D->getBuiltinTemplateKind()) {
- case BuiltinTemplateKind::BTK__make_integer_seq:
- ToD = Importer.getToContext().getMakeIntegerSeqDecl();
- break;
- case BuiltinTemplateKind::BTK__type_pack_element:
- ToD = Importer.getToContext().getTypePackElementDecl();
- break;
- }
- assert(ToD && "BuiltinTemplateDecl of unsupported kind!");
- Importer.MapImported(D, ToD);
- return ToD;
- }
- 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();
- }
- // 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);
- Error Err = Error::success();
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToAtStartLoc = importChecked(Err, D->getAtStartLoc());
- auto ToCategoryNameLoc = importChecked(Err, D->getCategoryNameLoc());
- if (Err)
- return std::move(Err);
- 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);
- Error Err = Error::success();
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToAtStartLoc = importChecked(Err, D->getAtStartLoc());
- auto ToSuperClassLoc = importChecked(Err, D->getSuperClassLoc());
- auto ToIvarLBraceLoc = importChecked(Err, D->getIvarLBraceLoc());
- auto ToIvarRBraceLoc = importChecked(Err, D->getIvarRBraceLoc());
- if (Err)
- return std::move(Err);
- 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)) {
- // Instance and class properties can share the same name but are different
- // declarations.
- if (FoundProp->isInstanceProperty() != D->isInstanceProperty())
- continue;
- // 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;
- }
- }
- Error Err = Error::success();
- auto ToType = importChecked(Err, D->getType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToAtLoc = importChecked(Err, D->getAtLoc());
- auto ToLParenLoc = importChecked(Err, D->getLParenLoc());
- if (Err)
- return std::move(Err);
- // Create the new property.
- ObjCPropertyDecl *ToProperty;
- if (GetImportedOrCreateDecl(
- ToProperty, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(), ToAtLoc,
- ToLParenLoc, ToType,
- ToTypeSourceInfo, D->getPropertyImplementation()))
- return ToProperty;
- auto ToGetterName = importChecked(Err, D->getGetterName());
- auto ToSetterName = importChecked(Err, D->getSetterName());
- auto ToGetterNameLoc = importChecked(Err, D->getGetterNameLoc());
- auto ToSetterNameLoc = importChecked(Err, D->getSetterNameLoc());
- auto ToGetterMethodDecl = importChecked(Err, D->getGetterMethodDecl());
- auto ToSetterMethodDecl = importChecked(Err, D->getSetterMethodDecl());
- auto ToPropertyIvarDecl = importChecked(Err, D->getPropertyIvarDecl());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToBeginLoc = importChecked(Err, D->getBeginLoc());
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToPropertyIvarDeclLoc =
- importChecked(Err, D->getPropertyIvarDeclLoc());
- if (Err)
- return std::move(Err);
- 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.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc LocationOrErr = import(D->getLocation());
- if (!LocationOrErr)
- return LocationOrErr.takeError();
- TemplateTypeParmDecl *ToD = nullptr;
- if (GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- *BeginLocOrErr, *LocationOrErr,
- D->getDepth(), D->getIndex(), Importer.Import(D->getIdentifier()),
- D->wasDeclaredWithTypename(), D->isParameterPack(),
- D->hasTypeConstraint()))
- return ToD;
- // Import the type-constraint
- if (const TypeConstraint *TC = D->getTypeConstraint()) {
- Error Err = Error::success();
- auto ToNNS = importChecked(Err, TC->getNestedNameSpecifierLoc());
- auto ToName = importChecked(Err, TC->getConceptNameInfo().getName());
- auto ToNameLoc = importChecked(Err, TC->getConceptNameInfo().getLoc());
- auto ToFoundDecl = importChecked(Err, TC->getFoundDecl());
- auto ToNamedConcept = importChecked(Err, TC->getNamedConcept());
- auto ToIDC = importChecked(Err, TC->getImmediatelyDeclaredConstraint());
- if (Err)
- return std::move(Err);
- TemplateArgumentListInfo ToTAInfo;
- const auto *ASTTemplateArgs = TC->getTemplateArgsAsWritten();
- if (ASTTemplateArgs)
- if (Error Err = ImportTemplateArgumentListInfo(*ASTTemplateArgs,
- ToTAInfo))
- return std::move(Err);
- ToD->setTypeConstraint(ToNNS, DeclarationNameInfo(ToName, ToNameLoc),
- ToFoundDecl, ToNamedConcept,
- ASTTemplateArgs ?
- ASTTemplateArgumentListInfo::Create(Importer.getToContext(),
- ToTAInfo) : nullptr,
- ToIDC);
- }
- if (D->hasDefaultArgument()) {
- Expected<TypeSourceInfo *> ToDefaultArgOrErr =
- import(D->getDefaultArgumentInfo());
- if (!ToDefaultArgOrErr)
- return ToDefaultArgOrErr.takeError();
- ToD->setDefaultArgument(*ToDefaultArgOrErr);
- }
- return ToD;
- }
- ExpectedDecl
- ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- Error Err = Error::success();
- auto ToDeclName = importChecked(Err, D->getDeclName());
- auto ToLocation = importChecked(Err, D->getLocation());
- auto ToType = importChecked(Err, D->getType());
- auto ToTypeSourceInfo = importChecked(Err, D->getTypeSourceInfo());
- auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart());
- if (Err)
- return std::move(Err);
- NonTypeTemplateParmDecl *ToD = nullptr;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- ToInnerLocStart, ToLocation, D->getDepth(),
- D->getPosition(),
- ToDeclName.getAsIdentifierInfo(), ToType,
- D->isParameterPack(), ToTypeSourceInfo))
- return ToD;
- if (D->hasDefaultArgument()) {
- ExpectedExpr ToDefaultArgOrErr = import(D->getDefaultArgument());
- if (!ToDefaultArgOrErr)
- return ToDefaultArgOrErr.takeError();
- ToD->setDefaultArgument(*ToDefaultArgOrErr);
- }
- 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();
- TemplateTemplateParmDecl *ToD = nullptr;
- if (GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr,
- D->getDepth(), D->getPosition(), D->isParameterPack(),
- (*NameOrErr).getAsIdentifierInfo(), *TemplateParamsOrErr))
- return ToD;
- if (D->hasDefaultArgument()) {
- Expected<TemplateArgumentLoc> ToDefaultArgOrErr =
- import(D->getDefaultArgument());
- if (!ToDefaultArgOrErr)
- return ToDefaultArgOrErr.takeError();
- ToD->setDefaultArgument(Importer.getToContext(), *ToDefaultArgOrErr);
- }
- 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) {
- // 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 (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
- continue;
- if (IsStructuralMatch(D, FoundTemplate)) {
- ClassTemplateDecl *TemplateWithDef =
- getTemplateDefinition(FoundTemplate);
- if (D->isThisDeclarationADefinition() && TemplateWithDef)
- return Importer.MapImported(D, TemplateWithDef);
- if (!FoundByLookup)
- FoundByLookup = FoundTemplate;
- // Search in all matches because there may be multiple decl chains,
- // see ASTTests test ImportExistingFriendClassTemplateDef.
- continue;
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- }
- if (!ConflictingDecls.empty()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, Decl::IDNS_Ordinary, ConflictingDecls.data(),
- ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- }
- CXXRecordDecl *FromTemplated = D->getTemplatedDecl();
- auto TemplateParamsOrErr = import(D->getTemplateParameters());
- if (!TemplateParamsOrErr)
- return TemplateParamsOrErr.takeError();
- // 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.
- 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);
- addDeclToContexts(D, D2);
- updateLookupTableForTemplateParameters(**TemplateParamsOrErr);
- 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 (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 and
- // template parameter list.
- void *InsertPos = nullptr;
- ClassTemplateSpecializationDecl *PrevDecl = nullptr;
- ClassTemplatePartialSpecializationDecl *PartialSpec =
- dyn_cast<ClassTemplatePartialSpecializationDecl>(D);
- // Import template parameters.
- TemplateParameterList *ToTPList = nullptr;
- if (PartialSpec) {
- auto ToTPListOrErr = import(PartialSpec->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
- ToTPList = *ToTPListOrErr;
- PrevDecl = ClassTemplate->findPartialSpecialization(TemplateArgs,
- *ToTPListOrErr,
- InsertPos);
- } else
- PrevDecl = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
- if (PrevDecl) {
- if (IsStructuralMatch(D, PrevDecl)) {
- CXXRecordDecl *PrevDefinition = PrevDecl->getDefinition();
- if (D->isThisDeclarationADefinition() && PrevDefinition) {
- Importer.MapImported(D, PrevDefinition);
- // 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 PrevDefinition;
- }
- } else { // ODR violation.
- // FIXME HandleNameConflict
- return make_error<ImportError>(ImportError::NameConflict);
- }
- }
- // 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();
- if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, ToTPList, 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.
- auto *PartSpec2 = cast<ClassTemplatePartialSpecializationDecl>(D2);
- if (!ClassTemplate->findPartialSpecialization(TemplateArgs, ToTPList,
- InsertPos))
- // Add this partial specialization to the class template.
- ClassTemplate->AddPartialSpecialization(PartSpec2, InsertPos);
- updateLookupTableForTemplateParameters(*ToTPList);
- } 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);
- }
- if (auto BraceRangeOrErr = import(D->getBraceRange()))
- D2->setBraceRange(*BraceRangeOrErr);
- else
- return BraceRangeOrErr.takeError();
- // 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) {
- // 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);
- VarTemplateDecl *FoundByLookup = nullptr;
- for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
- continue;
- if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(FoundDecl)) {
- // Use the templated decl, some linkage flags are set only there.
- if (!hasSameVisibilityContextAndLinkage(FoundTemplate->getTemplatedDecl(),
- D->getTemplatedDecl()))
- continue;
- if (IsStructuralMatch(D, FoundTemplate)) {
- // The Decl in the "From" context has a definition, but in the
- // "To" context we already have a definition.
- VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate);
- if (D->isThisDeclarationADefinition() && FoundDef)
- // FIXME Check for ODR error if the two definitions have
- // different initializers?
- return Importer.MapImported(D, FoundDef);
- FoundByLookup = FoundTemplate;
- break;
- }
- ConflictingDecls.push_back(FoundDecl);
- }
- }
- if (!ConflictingDecls.empty()) {
- ExpectedName NameOrErr = Importer.HandleNameConflict(
- Name, DC, Decl::IDNS_Ordinary, ConflictingDecls.data(),
- ConflictingDecls.size());
- if (NameOrErr)
- Name = NameOrErr.get();
- else
- return NameOrErr.takeError();
- }
- 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 (DC != Importer.getToContext().getTranslationUnitDecl())
- updateLookupTableForTemplateParameters(**TemplateParamsOrErr);
- if (FoundByLookup) {
- auto *Recent =
- const_cast<VarTemplateDecl *>(FoundByLookup->getMostRecentDecl());
- if (!ToTemplated->getPreviousDecl()) {
- auto *PrevTemplated =
- FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
- if (ToTemplated != PrevTemplated)
- ToTemplated->setPreviousDecl(PrevTemplated);
- }
- ToVarTD->setPreviousDecl(Recent);
- }
- 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;
- // FIXME: Use this update if VarTemplatePartialSpecializationDecl is fixed
- // to adopt template parameters.
- // updateLookupTableForTemplateParameters(**ToTPListOrErr);
- } 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 (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
- continue;
- 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();
- TemplateParameterList *Params = *ParamsOrErr;
- FunctionDecl *TemplatedFD;
- if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
- return std::move(Err);
- // At creation of the template the template parameters are "adopted"
- // (DeclContext is changed). After this possible change the lookup table
- // must be updated.
- // At deduction guides the DeclContext of the template parameters may be
- // different from what we would expect, it may be the class template, or a
- // probably different CXXDeductionGuideDecl. This may come from the fact that
- // the template parameter objects may be shared between deduction guides or
- // the class template, and at creation of multiple FunctionTemplateDecl
- // objects (for deduction guides) the same parameters are re-used. The
- // "adoption" happens multiple times with different parent, even recursively
- // for TemplateTemplateParmDecl. The same happens at import when the
- // FunctionTemplateDecl objects are created, but in different order.
- // In this way the DeclContext of these template parameters is not necessarily
- // the same as in the "from" context.
- SmallVector<DeclContext *, 2> OldParamDC;
- OldParamDC.reserve(Params->size());
- llvm::transform(*Params, std::back_inserter(OldParamDC),
- [](NamedDecl *ND) { return ND->getDeclContext(); });
- FunctionTemplateDecl *ToFunc;
- if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
- Params, TemplatedFD))
- return ToFunc;
- TemplatedFD->setDescribedFunctionTemplate(ToFunc);
- ToFunc->setAccess(D->getAccess());
- ToFunc->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(ToFunc);
- ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable();
- if (LT && !OldParamDC.empty()) {
- for (unsigned int I = 0; I < OldParamDC.size(); ++I)
- LT->updateForced(Params->getParam(I), OldParamDC[I]);
- }
- 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) {
- if (Importer.returnWithErrorInTest())
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- 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) {
- Error Err = Error::success();
- auto ToDG = importChecked(Err, S->getDeclGroup());
- auto ToBeginLoc = importChecked(Err, S->getBeginLoc());
- auto ToEndLoc = importChecked(Err, S->getEndLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToLHS = importChecked(Err, S->getLHS());
- auto ToRHS = importChecked(Err, S->getRHS());
- auto ToSubStmt = importChecked(Err, S->getSubStmt());
- auto ToCaseLoc = importChecked(Err, S->getCaseLoc());
- auto ToEllipsisLoc = importChecked(Err, S->getEllipsisLoc());
- auto ToColonLoc = importChecked(Err, S->getColonLoc());
- if (Err)
- return std::move(Err);
- auto *ToStmt = CaseStmt::Create(Importer.getToContext(), ToLHS, ToRHS,
- ToCaseLoc, ToEllipsisLoc, ToColonLoc);
- ToStmt->setSubStmt(ToSubStmt);
- return ToStmt;
- }
- ExpectedStmt ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
- Error Err = Error::success();
- auto ToDefaultLoc = importChecked(Err, S->getDefaultLoc());
- auto ToColonLoc = importChecked(Err, S->getColonLoc());
- auto ToSubStmt = importChecked(Err, S->getSubStmt());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) DefaultStmt(
- ToDefaultLoc, ToColonLoc, ToSubStmt);
- }
- ExpectedStmt ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
- Error Err = Error::success();
- auto ToIdentLoc = importChecked(Err, S->getIdentLoc());
- auto ToLabelDecl = importChecked(Err, S->getDecl());
- auto ToSubStmt = importChecked(Err, S->getSubStmt());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToIfLoc = importChecked(Err, S->getIfLoc());
- auto ToInit = importChecked(Err, S->getInit());
- auto ToConditionVariable = importChecked(Err, S->getConditionVariable());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToLParenLoc = importChecked(Err, S->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- auto ToThen = importChecked(Err, S->getThen());
- auto ToElseLoc = importChecked(Err, S->getElseLoc());
- auto ToElse = importChecked(Err, S->getElse());
- if (Err)
- return std::move(Err);
- return IfStmt::Create(Importer.getToContext(), ToIfLoc, S->getStatementKind(),
- ToInit, ToConditionVariable, ToCond, ToLParenLoc,
- ToRParenLoc, ToThen, ToElseLoc, ToElse);
- }
- ExpectedStmt ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
- Error Err = Error::success();
- auto ToInit = importChecked(Err, S->getInit());
- auto ToConditionVariable = importChecked(Err, S->getConditionVariable());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToLParenLoc = importChecked(Err, S->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- auto ToBody = importChecked(Err, S->getBody());
- auto ToSwitchLoc = importChecked(Err, S->getSwitchLoc());
- if (Err)
- return std::move(Err);
- auto *ToStmt =
- SwitchStmt::Create(Importer.getToContext(), ToInit, ToConditionVariable,
- ToCond, ToLParenLoc, ToRParenLoc);
- 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) {
- Error Err = Error::success();
- auto ToConditionVariable = importChecked(Err, S->getConditionVariable());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToBody = importChecked(Err, S->getBody());
- auto ToWhileLoc = importChecked(Err, S->getWhileLoc());
- auto ToLParenLoc = importChecked(Err, S->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- if (Err)
- return std::move(Err);
- return WhileStmt::Create(Importer.getToContext(), ToConditionVariable, ToCond,
- ToBody, ToWhileLoc, ToLParenLoc, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) {
- Error Err = Error::success();
- auto ToBody = importChecked(Err, S->getBody());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToDoLoc = importChecked(Err, S->getDoLoc());
- auto ToWhileLoc = importChecked(Err, S->getWhileLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) DoStmt(
- ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitForStmt(ForStmt *S) {
- Error Err = Error::success();
- auto ToInit = importChecked(Err, S->getInit());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToConditionVariable = importChecked(Err, S->getConditionVariable());
- auto ToInc = importChecked(Err, S->getInc());
- auto ToBody = importChecked(Err, S->getBody());
- auto ToForLoc = importChecked(Err, S->getForLoc());
- auto ToLParenLoc = importChecked(Err, S->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ForStmt(
- Importer.getToContext(),
- ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc, ToLParenLoc,
- ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
- Error Err = Error::success();
- auto ToLabel = importChecked(Err, S->getLabel());
- auto ToGotoLoc = importChecked(Err, S->getGotoLoc());
- auto ToLabelLoc = importChecked(Err, S->getLabelLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) GotoStmt(
- ToLabel, ToGotoLoc, ToLabelLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
- Error Err = Error::success();
- auto ToGotoLoc = importChecked(Err, S->getGotoLoc());
- auto ToStarLoc = importChecked(Err, S->getStarLoc());
- auto ToTarget = importChecked(Err, S->getTarget());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToReturnLoc = importChecked(Err, S->getReturnLoc());
- auto ToRetValue = importChecked(Err, S->getRetValue());
- auto ToNRVOCandidate = importChecked(Err, S->getNRVOCandidate());
- if (Err)
- return std::move(Err);
- return ReturnStmt::Create(Importer.getToContext(), ToReturnLoc, ToRetValue,
- ToNRVOCandidate);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
- Error Err = Error::success();
- auto ToCatchLoc = importChecked(Err, S->getCatchLoc());
- auto ToExceptionDecl = importChecked(Err, S->getExceptionDecl());
- auto ToHandlerBlock = importChecked(Err, S->getHandlerBlock());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToInit = importChecked(Err, S->getInit());
- auto ToRangeStmt = importChecked(Err, S->getRangeStmt());
- auto ToBeginStmt = importChecked(Err, S->getBeginStmt());
- auto ToEndStmt = importChecked(Err, S->getEndStmt());
- auto ToCond = importChecked(Err, S->getCond());
- auto ToInc = importChecked(Err, S->getInc());
- auto ToLoopVarStmt = importChecked(Err, S->getLoopVarStmt());
- auto ToBody = importChecked(Err, S->getBody());
- auto ToForLoc = importChecked(Err, S->getForLoc());
- auto ToCoawaitLoc = importChecked(Err, S->getCoawaitLoc());
- auto ToColonLoc = importChecked(Err, S->getColonLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) CXXForRangeStmt(
- ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
- ToBody, ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
- Error Err = Error::success();
- auto ToElement = importChecked(Err, S->getElement());
- auto ToCollection = importChecked(Err, S->getCollection());
- auto ToBody = importChecked(Err, S->getBody());
- auto ToForLoc = importChecked(Err, S->getForLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ObjCForCollectionStmt(ToElement,
- ToCollection,
- ToBody,
- ToForLoc,
- ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
- Error Err = Error::success();
- auto ToAtCatchLoc = importChecked(Err, S->getAtCatchLoc());
- auto ToRParenLoc = importChecked(Err, S->getRParenLoc());
- auto ToCatchParamDecl = importChecked(Err, S->getCatchParamDecl());
- auto ToCatchBody = importChecked(Err, S->getCatchBody());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToAtTryLoc = importChecked(Err, S->getAtTryLoc());
- auto ToTryBody = importChecked(Err, S->getTryBody());
- auto ToFinallyStmt = importChecked(Err, S->getFinallyStmt());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToAtSynchronizedLoc = importChecked(Err, S->getAtSynchronizedLoc());
- auto ToSynchExpr = importChecked(Err, S->getSynchExpr());
- auto ToSynchBody = importChecked(Err, S->getSynchBody());
- if (Err)
- return std::move(Err);
- 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::VisitSourceLocExpr(SourceLocExpr *E) {
- Error Err = Error::success();
- auto BLoc = importChecked(Err, E->getBeginLoc());
- auto RParenLoc = importChecked(Err, E->getEndLoc());
- if (Err)
- return std::move(Err);
- auto ParentContextOrErr = Importer.ImportContext(E->getParentContext());
- if (!ParentContextOrErr)
- return ParentContextOrErr.takeError();
- return new (Importer.getToContext())
- SourceLocExpr(Importer.getToContext(), E->getIdentKind(), BLoc, RParenLoc,
- *ParentContextOrErr);
- }
- ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
- Error Err = Error::success();
- auto ToBuiltinLoc = importChecked(Err, E->getBuiltinLoc());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToWrittenTypeInfo = importChecked(Err, E->getWrittenTypeInfo());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) VAArgExpr(
- ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType,
- E->isMicrosoftABI());
- }
- ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) {
- Error Err = Error::success();
- auto ToCond = importChecked(Err, E->getCond());
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToBuiltinLoc = importChecked(Err, E->getBuiltinLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- ExprValueKind VK = E->getValueKind();
- ExprObjectKind OK = E->getObjectKind();
- // 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);
- }
- ExpectedStmt ASTNodeImporter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
- Error Err = Error::success();
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToType = importChecked(Err, E->getType());
- const unsigned NumSubExprs = E->getNumSubExprs();
- llvm::SmallVector<Expr *, 8> ToSubExprs;
- llvm::ArrayRef<Expr *> FromSubExprs(E->getSubExprs(), NumSubExprs);
- ToSubExprs.resize(NumSubExprs);
- if ((Err = ImportContainerChecked(FromSubExprs, ToSubExprs)))
- return std::move(Err);
- return new (Importer.getToContext()) ShuffleVectorExpr(
- Importer.getToContext(), ToSubExprs, ToType, ToBeginLoc, ToRParenLoc);
- }
- 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::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
- Error Err = Error::success();
- auto ToGenericLoc = importChecked(Err, E->getGenericLoc());
- auto *ToControllingExpr = importChecked(Err, E->getControllingExpr());
- auto ToDefaultLoc = importChecked(Err, E->getDefaultLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- ArrayRef<const TypeSourceInfo *> FromAssocTypes(E->getAssocTypeSourceInfos());
- SmallVector<TypeSourceInfo *, 1> ToAssocTypes(FromAssocTypes.size());
- if (Error Err = ImportContainerChecked(FromAssocTypes, ToAssocTypes))
- return std::move(Err);
- ArrayRef<const Expr *> FromAssocExprs(E->getAssocExprs());
- SmallVector<Expr *, 1> ToAssocExprs(FromAssocExprs.size());
- if (Error Err = ImportContainerChecked(FromAssocExprs, ToAssocExprs))
- return std::move(Err);
- const ASTContext &ToCtx = Importer.getToContext();
- if (E->isResultDependent()) {
- return GenericSelectionExpr::Create(
- ToCtx, ToGenericLoc, ToControllingExpr,
- llvm::makeArrayRef(ToAssocTypes), llvm::makeArrayRef(ToAssocExprs),
- ToDefaultLoc, ToRParenLoc, E->containsUnexpandedParameterPack());
- }
- return GenericSelectionExpr::Create(
- ToCtx, ToGenericLoc, ToControllingExpr, llvm::makeArrayRef(ToAssocTypes),
- llvm::makeArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc,
- E->containsUnexpandedParameterPack(), E->getResultIndex());
- }
- ExpectedStmt ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
- Error Err = Error::success();
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToType = importChecked(Err, E->getType());
- auto ToFunctionName = importChecked(Err, E->getFunctionName());
- if (Err)
- return std::move(Err);
- return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType,
- E->getIdentKind(), ToFunctionName);
- }
- ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
- Error Err = Error::success();
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
- auto ToDecl = importChecked(Err, E->getDecl());
- auto ToLocation = importChecked(Err, E->getLocation());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- 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->getLAngleLoc(), E->getRAngleLoc(),
- 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, E->isNonOdrUse());
- 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::VisitFixedPointLiteral(FixedPointLiteral *E) {
- auto ToTypeOrErr = import(E->getType());
- if (!ToTypeOrErr)
- return ToTypeOrErr.takeError();
- ExpectedSLoc ToLocationOrErr = import(E->getLocation());
- if (!ToLocationOrErr)
- return ToLocationOrErr.takeError();
- return new (Importer.getToContext()) FixedPointLiteral(
- Importer.getToContext(), E->getValue(), *ToTypeOrErr, *ToLocationOrErr,
- Importer.getToContext().getFixedPointScale(*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) {
- Error Err = Error::success();
- auto ToLParenLoc = importChecked(Err, E->getLParenLoc());
- auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
- auto ToType = importChecked(Err, E->getType());
- auto ToInitializer = importChecked(Err, E->getInitializer());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) CompoundLiteralExpr(
- ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(),
- ToInitializer, E->isFileScope());
- }
- ExpectedStmt ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
- Error Err = Error::success();
- auto ToBuiltinLoc = importChecked(Err, E->getBuiltinLoc());
- auto ToType = importChecked(Err, E->getType());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToAmpAmpLoc = importChecked(Err, E->getAmpAmpLoc());
- auto ToLabelLoc = importChecked(Err, E->getLabelLoc());
- auto ToLabel = importChecked(Err, E->getLabel());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) AddrLabelExpr(
- ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
- Error Err = Error::success();
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToResult = importChecked(Err, E->getAPValueResult());
- if (Err)
- return std::move(Err);
- return ConstantExpr::Create(Importer.getToContext(), ToSubExpr, ToResult);
- }
- ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
- Error Err = Error::success();
- auto ToLParen = importChecked(Err, E->getLParen());
- auto ToRParen = importChecked(Err, E->getRParen());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToSubStmt = importChecked(Err, E->getSubStmt());
- auto ToType = importChecked(Err, E->getType());
- auto ToLParenLoc = importChecked(Err, E->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext())
- StmtExpr(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc,
- E->getTemplateDepth());
- }
- ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
- Error Err = Error::success();
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- if (Err)
- return std::move(Err);
- return UnaryOperator::Create(
- Importer.getToContext(), ToSubExpr, E->getOpcode(), ToType,
- E->getValueKind(), E->getObjectKind(), ToOperatorLoc, E->canOverflow(),
- E->getFPOptionsOverride());
- }
- ExpectedStmt
- ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- if (Err)
- return std::move(Err);
- return BinaryOperator::Create(
- Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
- E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
- E->getFPFeatures(Importer.getFromContext().getLangOpts()));
- }
- ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
- Error Err = Error::success();
- auto ToCond = importChecked(Err, E->getCond());
- auto ToQuestionLoc = importChecked(Err, E->getQuestionLoc());
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToColonLoc = importChecked(Err, E->getColonLoc());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ConditionalOperator(
- ToCond, ToQuestionLoc, ToLHS, ToColonLoc, ToRHS, ToType,
- E->getValueKind(), E->getObjectKind());
- }
- ExpectedStmt
- ASTNodeImporter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
- Error Err = Error::success();
- auto ToCommon = importChecked(Err, E->getCommon());
- auto ToOpaqueValue = importChecked(Err, E->getOpaqueValue());
- auto ToCond = importChecked(Err, E->getCond());
- auto ToTrueExpr = importChecked(Err, E->getTrueExpr());
- auto ToFalseExpr = importChecked(Err, E->getFalseExpr());
- auto ToQuestionLoc = importChecked(Err, E->getQuestionLoc());
- auto ToColonLoc = importChecked(Err, E->getColonLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) BinaryConditionalOperator(
- ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr,
- ToQuestionLoc, ToColonLoc, ToType, E->getValueKind(),
- E->getObjectKind());
- }
- ExpectedStmt ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
- Error Err = Error::success();
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToQueriedTypeSourceInfo =
- importChecked(Err, E->getQueriedTypeSourceInfo());
- auto ToDimensionExpression = importChecked(Err, E->getDimensionExpression());
- auto ToEndLoc = importChecked(Err, E->getEndLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ArrayTypeTraitExpr(
- ToBeginLoc, E->getTrait(), ToQueriedTypeSourceInfo, E->getValue(),
- ToDimensionExpression, ToEndLoc, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
- Error Err = Error::success();
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToQueriedExpression = importChecked(Err, E->getQueriedExpression());
- auto ToEndLoc = importChecked(Err, E->getEndLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ExpressionTraitExpr(
- ToBeginLoc, E->getTrait(), ToQueriedExpression, E->getValue(),
- ToEndLoc, ToType);
- }
- ExpectedStmt ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
- Error Err = Error::success();
- auto ToLocation = importChecked(Err, E->getLocation());
- auto ToType = importChecked(Err, E->getType());
- auto ToSourceExpr = importChecked(Err, E->getSourceExpr());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) OpaqueValueExpr(
- ToLocation, ToType, E->getValueKind(), E->getObjectKind(), ToSourceExpr);
- }
- ExpectedStmt ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
- Error Err = Error::success();
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToType = importChecked(Err, E->getType());
- auto ToRBracketLoc = importChecked(Err, E->getRBracketLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) ArraySubscriptExpr(
- ToLHS, ToRHS, ToType, E->getValueKind(), E->getObjectKind(),
- ToRBracketLoc);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
- Error Err = Error::success();
- auto ToLHS = importChecked(Err, E->getLHS());
- auto ToRHS = importChecked(Err, E->getRHS());
- auto ToType = importChecked(Err, E->getType());
- auto ToComputationLHSType = importChecked(Err, E->getComputationLHSType());
- auto ToComputationResultType =
- importChecked(Err, E->getComputationResultType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- if (Err)
- return std::move(Err);
- return CompoundAssignOperator::Create(
- Importer.getToContext(), ToLHS, ToRHS, E->getOpcode(), ToType,
- E->getValueKind(), E->getObjectKind(), ToOperatorLoc,
- E->getFPFeatures(Importer.getFromContext().getLangOpts()),
- ToComputationLHSType, ToComputationResultType);
- }
- 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(), E->getFPFeatures());
- }
- ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToTypeInfoAsWritten = importChecked(Err, E->getTypeInfoAsWritten());
- if (Err)
- return std::move(Err);
- 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, CCE->getFPFeatures(), 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, FCE->getFPFeatures(),
- *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) {
- Error Err = Error::success();
- ToBeginLoc = importChecked(Err, FromNode.getBeginLoc());
- ToEndLoc = importChecked(Err, FromNode.getEndLoc());
- if (Err)
- return std::move(Err);
- }
- 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;
- }
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- return OffsetOfExpr::Create(
- Importer.getToContext(), ToType, ToOperatorLoc, ToTypeSourceInfo, ToNodes,
- ToExprs, ToRParenLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToOperand = importChecked(Err, E->getOperand());
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToEndLoc = importChecked(Err, E->getEndLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToType = importChecked(Err, E->getType());
- auto ToThrowLoc = importChecked(Err, E->getThrowLoc());
- if (Err)
- return std::move(Err);
- 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();
- // Import the default arg if it was not imported yet.
- // This is needed because it can happen that during the import of the
- // default expression (from VisitParmVarDecl) the same ParmVarDecl is
- // encountered here. The default argument for a ParmVarDecl is set in the
- // ParmVarDecl only after it is imported (set in VisitParmVarDecl if not here,
- // see VisitParmVarDecl).
- ParmVarDecl *ToParam = *ToParamOrErr;
- if (!ToParam->getDefaultArg()) {
- Optional<ParmVarDecl *> FromParam = Importer.getImportedFromDecl(ToParam);
- assert(FromParam && "ParmVarDecl was not imported?");
- if (Error Err = ImportDefaultArgOfParmVarDecl(*FromParam, ToParam))
- return std::move(Err);
- }
- return CXXDefaultArgExpr::Create(Importer.getToContext(), *ToUsedLocOrErr,
- *ToParamOrErr, *UsedContextOrErr);
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToConstructor = importChecked(Err, E->getConstructor());
- auto ToType = importChecked(Err, E->getType());
- auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
- auto ToParenOrBraceRange = importChecked(Err, E->getParenOrBraceRange());
- if (Err)
- return std::move(Err);
- 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());
- }
- ExpectedDecl ASTNodeImporter::VisitLifetimeExtendedTemporaryDecl(
- LifetimeExtendedTemporaryDecl *D) {
- DeclContext *DC, *LexicalDC;
- if (Error Err = ImportDeclContext(D, DC, LexicalDC))
- return std::move(Err);
- Error Err = Error::success();
- auto Temporary = importChecked(Err, D->getTemporaryExpr());
- auto ExtendingDecl = importChecked(Err, D->getExtendingDecl());
- if (Err)
- return std::move(Err);
- // FIXME: Should ManglingNumber get numbers associated with 'to' context?
- LifetimeExtendedTemporaryDecl *To;
- if (GetImportedOrCreateDecl(To, D, Temporary, ExtendingDecl,
- D->getManglingNumber()))
- return To;
- To->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(To);
- return To;
- }
- ExpectedStmt
- ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- Expr *ToTemporaryExpr = importChecked(
- Err, E->getLifetimeExtendedTemporaryDecl() ? nullptr : E->getSubExpr());
- auto ToMaterializedDecl =
- importChecked(Err, E->getLifetimeExtendedTemporaryDecl());
- if (Err)
- return std::move(Err);
- if (!ToTemporaryExpr)
- ToTemporaryExpr = cast<Expr>(ToMaterializedDecl->getTemporaryExpr());
- auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr(
- ToType, ToTemporaryExpr, E->isBoundToLvalueReference(),
- ToMaterializedDecl);
- return ToMTE;
- }
- ExpectedStmt ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToPattern = importChecked(Err, E->getPattern());
- auto ToEllipsisLoc = importChecked(Err, E->getEllipsisLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) PackExpansionExpr(
- ToType, ToPattern, ToEllipsisLoc, E->getNumExpansions());
- }
- ExpectedStmt ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
- Error Err = Error::success();
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToPack = importChecked(Err, E->getPack());
- auto ToPackLoc = importChecked(Err, E->getPackLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToOperatorNew = importChecked(Err, E->getOperatorNew());
- auto ToOperatorDelete = importChecked(Err, E->getOperatorDelete());
- auto ToTypeIdParens = importChecked(Err, E->getTypeIdParens());
- auto ToArraySize = importChecked(Err, E->getArraySize());
- auto ToInitializer = importChecked(Err, E->getInitializer());
- auto ToType = importChecked(Err, E->getType());
- auto ToAllocatedTypeSourceInfo =
- importChecked(Err, E->getAllocatedTypeSourceInfo());
- auto ToSourceRange = importChecked(Err, E->getSourceRange());
- auto ToDirectInitRange = importChecked(Err, E->getDirectInitRange());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorDelete = importChecked(Err, E->getOperatorDelete());
- auto ToArgument = importChecked(Err, E->getArgument());
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) CXXDeleteExpr(
- ToType, E->isGlobalDelete(), E->isArrayForm(), E->isArrayFormAsWritten(),
- E->doesUsualArrayDeleteWantSize(), ToOperatorDelete, ToArgument,
- ToBeginLoc);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToLocation = importChecked(Err, E->getLocation());
- auto ToConstructor = importChecked(Err, E->getConstructor());
- auto ToParenOrBraceRange = importChecked(Err, E->getParenOrBraceRange());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToCallee = importChecked(Err, E->getCallee());
- auto ToType = importChecked(Err, E->getType());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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,
- E->getFPFeatures());
- }
- 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) {
- Error Err = Error::success();
- auto ToBase = importChecked(Err, E->getBase());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
- auto ToMemberDecl = importChecked(Err, E->getMemberDecl());
- auto ToType = importChecked(Err, E->getType());
- auto ToDecl = importChecked(Err, E->getFoundDecl().getDecl());
- auto ToName = importChecked(Err, E->getMemberNameInfo().getName());
- auto ToLoc = importChecked(Err, E->getMemberNameInfo().getLoc());
- if (Err)
- return std::move(Err);
- 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(), E->isNonOdrUse());
- }
- ExpectedStmt
- ASTNodeImporter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
- Error Err = Error::success();
- auto ToBase = importChecked(Err, E->getBase());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToScopeTypeInfo = importChecked(Err, E->getScopeTypeInfo());
- auto ToColonColonLoc = importChecked(Err, E->getColonColonLoc());
- auto ToTildeLoc = importChecked(Err, E->getTildeLoc());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
- auto ToFirstQualifierFoundInScope =
- importChecked(Err, E->getFirstQualifierFoundInScope());
- if (Err)
- return std::move(Err);
- 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 ToMember = importChecked(Err, E->getMember());
- auto ToMemberLoc = importChecked(Err, E->getMemberLoc());
- if (Err)
- return std::move(Err);
- DeclarationNameInfo ToMemberNameInfo(ToMember, ToMemberLoc);
- // 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) {
- Error Err = Error::success();
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
- auto ToDeclName = importChecked(Err, E->getDeclName());
- auto ToNameLoc = importChecked(Err, E->getNameInfo().getLoc());
- auto ToLAngleLoc = importChecked(Err, E->getLAngleLoc());
- auto ToRAngleLoc = importChecked(Err, E->getRAngleLoc());
- if (Err)
- return std::move(Err);
- DeclarationNameInfo ToNameInfo(ToDeclName, ToNameLoc);
- 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) {
- Error Err = Error::success();
- auto ToLParenLoc = importChecked(Err, E->getLParenLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- auto ToType = importChecked(Err, E->getType());
- auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
- if (Err)
- return std::move(Err);
- SmallVector<Expr *, 8> ToArgs(E->getNumArgs());
- if (Error Err =
- ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin()))
- return std::move(Err);
- return CXXUnresolvedConstructExpr::Create(
- Importer.getToContext(), ToType, 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();
- Error Err = Error::success();
- auto ToName = importChecked(Err, E->getName());
- auto ToNameLoc = importChecked(Err, E->getNameLoc());
- if (Err)
- return std::move(Err);
- DeclarationNameInfo ToNameInfo(ToName, ToNameLoc);
- // 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()) {
- 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) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToQualifierLoc = importChecked(Err, E->getQualifierLoc());
- auto ToTemplateKeywordLoc = importChecked(Err, E->getTemplateKeywordLoc());
- auto ToName = importChecked(Err, E->getName());
- auto ToNameLoc = importChecked(Err, E->getNameLoc());
- if (Err)
- return std::move(Err);
- DeclarationNameInfo ToNameInfo(ToName, ToNameLoc);
- // 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()) {
- TemplateArgumentListInfo FromTAInfo;
- E->copyTemplateArgumentsInto(FromTAInfo);
- if (Error Err = ImportTemplateArgumentListInfo(FromTAInfo, 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) {
- Error Err = Error::success();
- auto ToCallee = importChecked(Err, E->getCallee());
- auto ToType = importChecked(Err, E->getType());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- 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, E->getFPFeatures(),
- /*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;
- auto ToCallOpOrErr = import(E->getCallOperator());
- if (!ToCallOpOrErr)
- return ToCallOpOrErr.takeError();
- SmallVector<Expr *, 8> ToCaptureInits(E->capture_size());
- if (Error Err = ImportContainerChecked(E->capture_inits(), ToCaptureInits))
- return std::move(Err);
- Error Err = Error::success();
- auto ToIntroducerRange = importChecked(Err, E->getIntroducerRange());
- auto ToCaptureDefaultLoc = importChecked(Err, E->getCaptureDefaultLoc());
- auto ToEndLoc = importChecked(Err, E->getEndLoc());
- if (Err)
- return std::move(Err);
- return LambdaExpr::Create(Importer.getToContext(), ToClass, ToIntroducerRange,
- E->getCaptureDefault(), ToCaptureDefaultLoc,
- E->hasExplicitParameters(),
- E->hasExplicitResultType(), ToCaptureInits,
- ToEndLoc, E->containsUnexpandedParameterPack());
- }
- ExpectedStmt ASTNodeImporter::VisitInitListExpr(InitListExpr *E) {
- Error Err = Error::success();
- auto ToLBraceLoc = importChecked(Err, E->getLBraceLoc());
- auto ToRBraceLoc = importChecked(Err, E->getRBraceLoc());
- auto ToType = importChecked(Err, E->getType());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToLocation = importChecked(Err, E->getLocation());
- auto ToType = importChecked(Err, E->getType());
- auto ToConstructor = importChecked(Err, E->getConstructor());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) CXXInheritedCtorInitExpr(
- ToLocation, ToType, ToConstructor, E->constructsVBase(),
- E->inheritedFromVBase());
- }
- ExpectedStmt ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToCommonExpr = importChecked(Err, E->getCommonExpr());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- if (Err)
- return std::move(Err);
- 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) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToSubExpr = importChecked(Err, E->getSubExpr());
- auto ToTypeInfoAsWritten = importChecked(Err, E->getTypeInfoAsWritten());
- auto ToOperatorLoc = importChecked(Err, E->getOperatorLoc());
- auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
- auto ToAngleBrackets = importChecked(Err, E->getAngleBrackets());
- if (Err)
- return std::move(Err);
- ExprValueKind VK = E->getValueKind();
- CastKind CK = E->getCastKind();
- auto ToBasePathOrErr = ImportCastPath(E);
- if (!ToBasePathOrErr)
- return ToBasePathOrErr.takeError();
- if (auto CCE = dyn_cast<CXXStaticCastExpr>(E)) {
- return CXXStaticCastExpr::Create(
- Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
- ToTypeInfoAsWritten, CCE->getFPFeatures(), 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) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToExprLoc = importChecked(Err, E->getExprLoc());
- auto ToParameter = importChecked(Err, E->getParameter());
- auto ToReplacement = importChecked(Err, E->getReplacement());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
- ToType, E->getValueKind(), ToExprLoc, ToParameter,
- E->isReferenceParameter(), ToReplacement);
- }
- ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToBeginLoc = importChecked(Err, E->getBeginLoc());
- auto ToEndLoc = importChecked(Err, E->getEndLoc());
- if (Err)
- return std::move(Err);
- 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);
- }
- ExpectedStmt ASTNodeImporter::VisitCXXFoldExpr(CXXFoldExpr *E) {
- Error Err = Error::success();
- QualType ToType = importChecked(Err, E->getType());
- UnresolvedLookupExpr *ToCallee = importChecked(Err, E->getCallee());
- SourceLocation ToLParenLoc = importChecked(Err, E->getLParenLoc());
- Expr *ToLHS = importChecked(Err, E->getLHS());
- SourceLocation ToEllipsisLoc = importChecked(Err, E->getEllipsisLoc());
- Expr *ToRHS = importChecked(Err, E->getRHS());
- SourceLocation ToRParenLoc = importChecked(Err, E->getRParenLoc());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext())
- CXXFoldExpr(ToType, ToCallee, ToLParenLoc, ToLHS, E->getOperator(),
- ToEllipsisLoc, ToRHS, ToRParenLoc, E->getNumExpansions());
- }
- Error ASTNodeImporter::ImportOverriddenMethods(CXXMethodDecl *ToMethod,
- CXXMethodDecl *FromMethod) {
- Error ImportErrors = Error::success();
- for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) {
- if (auto ImportedOrErr = import(FromOverriddenMethod))
- ToMethod->getCanonicalDecl()->addOverriddenMethod(cast<CXXMethodDecl>(
- (*ImportedOrErr)->getCanonicalDecl()));
- else
- ImportErrors =
- joinErrors(std::move(ImportErrors), ImportedOrErr.takeError());
- }
- return ImportErrors;
- }
- ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
- ASTContext &FromContext, FileManager &FromFileManager,
- bool MinimalImport,
- std::shared_ptr<ASTImporterSharedState> SharedState)
- : SharedState(SharedState), ToContext(ToContext), FromContext(FromContext),
- ToFileManager(ToFileManager), FromFileManager(FromFileManager),
- Minimal(MinimalImport), ODRHandling(ODRHandlingType::Conservative) {
- // Create a default state without the lookup table: LLDB case.
- if (!SharedState) {
- this->SharedState = std::make_shared<ASTImporterSharedState>();
- }
- 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 (SharedState->getLookupTable()) {
- ASTImporterLookupTable::LookupResult LookupResult =
- SharedState->getLookupTable()->lookup(ReDC, Name);
- return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
- } else {
- DeclContext::lookup_result NoloadLookupResult = ReDC->noload_lookup(Name);
- FoundDeclsTy Result(NoloadLookupResult.begin(), NoloadLookupResult.end());
- // We must search by the slow case of localUncachedLookup because that is
- // working even if there is no LookupPtr for the DC. We could use
- // DC::buildLookup() to create the LookupPtr, but that would load external
- // decls again, we must avoid that case.
- // Also, even if we had the LookupPtr, we must find Decls which are not
- // in the LookupPtr, so we need the slow case.
- // These cases are handled in ASTImporterLookupTable, but we cannot use
- // that with LLDB since that traverses through the AST which initiates the
- // load of external decls again via DC::decls(). And again, we must avoid
- // loading external decls during the import.
- if (Result.empty())
- ReDC->localUncachedLookup(Name, Result);
- return Result;
- }
- }
- void ASTImporter::AddToLookupTable(Decl *ToD) {
- SharedState->addDeclToLookup(ToD);
- }
- 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);
- }
- llvm::Expected<ExprWithCleanups::CleanupObject>
- ASTImporter::Import(ExprWithCleanups::CleanupObject From) {
- if (auto *CLE = From.dyn_cast<CompoundLiteralExpr *>()) {
- if (Expected<Expr *> R = Import(CLE))
- return ExprWithCleanups::CleanupObject(cast<CompoundLiteralExpr>(*R));
- }
- // FIXME: Handle BlockDecl when we implement importing BlockExpr in
- // ASTNodeImporter.
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
- }
- ExpectedTypePtr ASTImporter::Import(const Type *FromT) {
- if (!FromT)
- return FromT;
- // Check whether we've already imported this type.
- llvm::DenseMap<const Type *, const Type *>::iterator Pos =
- ImportedTypes.find(FromT);
- if (Pos != ImportedTypes.end())
- return Pos->second;
- // Import the type.
- ASTNodeImporter Importer(*this);
- ExpectedType ToTOrErr = Importer.Visit(FromT);
- if (!ToTOrErr)
- return ToTOrErr.takeError();
- // Record the imported type.
- ImportedTypes[FromT] = ToTOrErr->getTypePtr();
- return ToTOrErr->getTypePtr();
- }
- Expected<QualType> ASTImporter::Import(QualType FromT) {
- if (FromT.isNull())
- return QualType{};
- ExpectedTypePtr ToTyOrErr = Import(FromT.getTypePtr());
- if (!ToTyOrErr)
- return ToTyOrErr.takeError();
- return ToContext.getQualifiedType(*ToTyOrErr, 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);
- }
- // To use this object, it should be created before the new attribute is created,
- // and destructed after it is created. The construction already performs the
- // import of the data.
- template <typename T> struct AttrArgImporter {
- AttrArgImporter(const AttrArgImporter<T> &) = delete;
- AttrArgImporter(AttrArgImporter<T> &&) = default;
- AttrArgImporter<T> &operator=(const AttrArgImporter<T> &) = delete;
- AttrArgImporter<T> &operator=(AttrArgImporter<T> &&) = default;
- AttrArgImporter(ASTNodeImporter &I, Error &Err, const T &From)
- : To(I.importChecked(Err, From)) {}
- const T &value() { return To; }
- private:
- T To;
- };
- // To use this object, it should be created before the new attribute is created,
- // and destructed after it is created. The construction already performs the
- // import of the data. The array data is accessible in a pointer form, this form
- // is used by the attribute classes. This object should be created once for the
- // array data to be imported (the array size is not imported, just copied).
- template <typename T> struct AttrArgArrayImporter {
- AttrArgArrayImporter(const AttrArgArrayImporter<T> &) = delete;
- AttrArgArrayImporter(AttrArgArrayImporter<T> &&) = default;
- AttrArgArrayImporter<T> &operator=(const AttrArgArrayImporter<T> &) = delete;
- AttrArgArrayImporter<T> &operator=(AttrArgArrayImporter<T> &&) = default;
- AttrArgArrayImporter(ASTNodeImporter &I, Error &Err,
- const llvm::iterator_range<T *> &From,
- unsigned ArraySize) {
- if (Err)
- return;
- To.reserve(ArraySize);
- Err = I.ImportContainerChecked(From, To);
- }
- T *value() { return To.data(); }
- private:
- llvm::SmallVector<T, 2> To;
- };
- class AttrImporter {
- Error Err{Error::success()};
- Attr *ToAttr = nullptr;
- ASTImporter &Importer;
- ASTNodeImporter NImporter;
- public:
- AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
- // Create an "importer" for an attribute parameter.
- // Result of the 'value()' of that object is to be passed to the function
- // 'importAttr', in the order that is expected by the attribute class.
- template <class T> AttrArgImporter<T> importArg(const T &From) {
- return AttrArgImporter<T>(NImporter, Err, From);
- }
- // Create an "importer" for an attribute parameter that has array type.
- // Result of the 'value()' of that object is to be passed to the function
- // 'importAttr', then the size of the array as next argument.
- template <typename T>
- AttrArgArrayImporter<T> importArrayArg(const llvm::iterator_range<T *> &From,
- unsigned ArraySize) {
- return AttrArgArrayImporter<T>(NImporter, Err, From, ArraySize);
- }
- // Create an attribute object with the specified arguments.
- // The 'FromAttr' is the original (not imported) attribute, the 'ImportedArg'
- // should be values that are passed to the 'Create' function of the attribute.
- // (The 'Create' with 'ASTContext' first and 'AttributeCommonInfo' last is
- // used here.) As much data is copied or imported from the old attribute
- // as possible. The passed arguments should be already imported.
- // If an import error happens, the internal error is set to it, and any
- // further import attempt is ignored.
- template <typename T, typename... Arg>
- void importAttr(const T *FromAttr, Arg &&...ImportedArg) {
- static_assert(std::is_base_of<Attr, T>::value,
- "T should be subclass of Attr.");
- assert(!ToAttr && "Use one AttrImporter to import one Attribute object.");
- const IdentifierInfo *ToAttrName = Importer.Import(FromAttr->getAttrName());
- const IdentifierInfo *ToScopeName =
- Importer.Import(FromAttr->getScopeName());
- SourceRange ToAttrRange =
- NImporter.importChecked(Err, FromAttr->getRange());
- SourceLocation ToScopeLoc =
- NImporter.importChecked(Err, FromAttr->getScopeLoc());
- if (Err)
- return;
- AttributeCommonInfo ToI(ToAttrName, ToScopeName, ToAttrRange, ToScopeLoc,
- FromAttr->getParsedKind(), FromAttr->getSyntax(),
- FromAttr->getAttributeSpellingListIndex());
- // The "SemanticSpelling" is not needed to be passed to the constructor.
- // That value is recalculated from the SpellingListIndex if needed.
- ToAttr = T::Create(Importer.getToContext(),
- std::forward<Arg>(ImportedArg)..., ToI);
- ToAttr->setImplicit(FromAttr->isImplicit());
- ToAttr->setPackExpansion(FromAttr->isPackExpansion());
- if (auto *ToInheritableAttr = dyn_cast<InheritableAttr>(ToAttr))
- ToInheritableAttr->setInherited(FromAttr->isInherited());
- }
- // Create a clone of the 'FromAttr' and import its source range only.
- // This causes objects with invalid references to be created if the 'FromAttr'
- // contains other data that should be imported.
- void cloneAttr(const Attr *FromAttr) {
- assert(!ToAttr && "Use one AttrImporter to import one Attribute object.");
- SourceRange ToRange = NImporter.importChecked(Err, FromAttr->getRange());
- if (Err)
- return;
- ToAttr = FromAttr->clone(Importer.getToContext());
- ToAttr->setRange(ToRange);
- }
- // Get the result of the previous import attempt (can be used only once).
- llvm::Expected<Attr *> getResult() && {
- if (Err)
- return std::move(Err);
- assert(ToAttr && "Attribute should be created.");
- return ToAttr;
- }
- };
- Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
- AttrImporter AI(*this);
- // FIXME: Is there some kind of AttrVisitor to use here?
- switch (FromAttr->getKind()) {
- case attr::Aligned: {
- auto *From = cast<AlignedAttr>(FromAttr);
- if (From->isAlignmentExpr())
- AI.importAttr(From, true, AI.importArg(From->getAlignmentExpr()).value());
- else
- AI.importAttr(From, false,
- AI.importArg(From->getAlignmentType()).value());
- break;
- }
- case attr::Format: {
- const auto *From = cast<FormatAttr>(FromAttr);
- AI.importAttr(From, Import(From->getType()), From->getFormatIdx(),
- From->getFirstArg());
- break;
- }
- case attr::AssertCapability: {
- const auto *From = cast<AssertCapabilityAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::AcquireCapability: {
- const auto *From = cast<AcquireCapabilityAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::TryAcquireCapability: {
- const auto *From = cast<TryAcquireCapabilityAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::ReleaseCapability: {
- const auto *From = cast<ReleaseCapabilityAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::RequiresCapability: {
- const auto *From = cast<RequiresCapabilityAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::GuardedBy: {
- const auto *From = cast<GuardedByAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getArg()).value());
- break;
- }
- case attr::PtGuardedBy: {
- const auto *From = cast<PtGuardedByAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getArg()).value());
- break;
- }
- case attr::AcquiredAfter: {
- const auto *From = cast<AcquiredAfterAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::AcquiredBefore: {
- const auto *From = cast<AcquiredBeforeAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::AssertExclusiveLock: {
- const auto *From = cast<AssertExclusiveLockAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::AssertSharedLock: {
- const auto *From = cast<AssertSharedLockAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::ExclusiveTrylockFunction: {
- const auto *From = cast<ExclusiveTrylockFunctionAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::SharedTrylockFunction: {
- const auto *From = cast<SharedTrylockFunctionAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getSuccessValue()).value(),
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- case attr::LockReturned: {
- const auto *From = cast<LockReturnedAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getArg()).value());
- break;
- }
- case attr::LocksExcluded: {
- const auto *From = cast<LocksExcludedAttr>(FromAttr);
- AI.importAttr(From,
- AI.importArrayArg(From->args(), From->args_size()).value(),
- From->args_size());
- break;
- }
- default: {
- // The default branch works for attributes that have no arguments to import.
- // FIXME: Handle every attribute type that has arguments of type to import
- // (most often Expr* or Decl* or type) in the switch above.
- AI.cloneAttr(FromAttr);
- break;
- }
- }
- return std::move(AI).getResult();
- }
- 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;
- // Push FromD to the stack, and remove that when we return.
- ImportPath.push(FromD);
- auto ImportPathBuilder =
- llvm::make_scope_exit([this]() { ImportPath.pop(); });
- // Check whether there was a previous failed import.
- // If yes return the existing error.
- if (auto Error = getImportDeclErrorIfAny(FromD))
- return make_error<ImportError>(*Error);
- // Check whether we've already imported this declaration.
- Decl *ToD = GetAlreadyImportedOrNull(FromD);
- if (ToD) {
- // Already imported (possibly from another TU) and with an error.
- if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
- setImportDeclError(FromD, *Error);
- return make_error<ImportError>(*Error);
- }
- // If FromD has some updated flags after last import, apply it.
- updateFlags(FromD, ToD);
- // If we encounter a cycle during an import then we save the relevant part
- // of the import path associated to the Decl.
- if (ImportPath.hasCycleAtBack())
- SavedImportPaths[FromD].push_back(ImportPath.copyCycleAtBack());
- return ToD;
- }
- // Import the declaration.
- ExpectedDecl ToDOrErr = ImportImpl(FromD);
- if (!ToDOrErr) {
- // Failed to import.
- auto Pos = ImportedDecls.find(FromD);
- if (Pos != ImportedDecls.end()) {
- // Import failed after the object was created.
- // Remove all references to it.
- auto *ToD = Pos->second;
- ImportedDecls.erase(Pos);
- // ImportedDecls and ImportedFromDecls are not symmetric. It may happen
- // (e.g. with namespaces) that several decls from the 'from' context are
- // mapped to the same decl in the 'to' context. If we removed entries
- // from the LookupTable here then we may end up removing them multiple
- // times.
- // The Lookuptable contains decls only which are in the 'to' context.
- // Remove from the Lookuptable only if it is *imported* into the 'to'
- // context (and do not remove it if it was added during the initial
- // traverse of the 'to' context).
- auto PosF = ImportedFromDecls.find(ToD);
- if (PosF != ImportedFromDecls.end()) {
- // In the case of TypedefNameDecl we create the Decl first and only
- // then we import and set its DeclContext. So, the DC might not be set
- // when we reach here.
- if (ToD->getDeclContext())
- SharedState->removeDeclFromLookup(ToD);
- ImportedFromDecls.erase(PosF);
- }
- // FIXME: AST may contain remaining references to the failed object.
- // However, the ImportDeclErrors in the shared state contains all the
- // failed objects together with their error.
- }
- // Error encountered for the first time.
- // After takeError the error is not usable any more in ToDOrErr.
- // Get a copy of the error object (any more simple solution for this?).
- ImportError ErrOut;
- handleAllErrors(ToDOrErr.takeError(),
- [&ErrOut](const ImportError &E) { ErrOut = E; });
- setImportDeclError(FromD, ErrOut);
- // Set the error for the mapped to Decl, which is in the "to" context.
- if (Pos != ImportedDecls.end())
- SharedState->setImportDeclError(Pos->second, ErrOut);
- // Set the error for all nodes which have been created before we
- // recognized the error.
- for (const auto &Path : SavedImportPaths[FromD])
- for (Decl *FromDi : Path) {
- setImportDeclError(FromDi, ErrOut);
- //FIXME Should we remove these Decls from ImportedDecls?
- // Set the error for the mapped to Decl, which is in the "to" context.
- auto Ii = ImportedDecls.find(FromDi);
- if (Ii != ImportedDecls.end())
- SharedState->setImportDeclError(Ii->second, ErrOut);
- // FIXME Should we remove these Decls from the LookupTable,
- // and from ImportedFromDecls?
- }
- SavedImportPaths.erase(FromD);
- // Do not return ToDOrErr, error was taken out of it.
- return make_error<ImportError>(ErrOut);
- }
- ToD = *ToDOrErr;
- // FIXME: Handle the "already imported with error" case. We can get here
- // nullptr only if GetImportedOrCreateDecl returned nullptr (after a
- // previously failed create was requested).
- // Later GetImportedOrCreateDecl can be updated to return the error.
- if (!ToD) {
- auto Err = getImportDeclErrorIfAny(FromD);
- assert(Err);
- return make_error<ImportError>(*Err);
- }
- // We could import from the current TU without error. But previously we
- // already had imported a Decl as `ToD` from another TU (with another
- // ASTImporter object) and with an error.
- if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
- setImportDeclError(FromD, *Error);
- return make_error<ImportError>(*Error);
- }
- // Make sure that ImportImpl registered the imported decl.
- assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
- if (FromD->hasAttrs())
- for (const Attr *FromAttr : FromD->getAttrs()) {
- auto ToAttrOrErr = Import(FromAttr);
- if (ToAttrOrErr)
- ToD->addAttr(*ToAttrOrErr);
- else
- return ToAttrOrErr.takeError();
- }
- // Notify subclasses.
- Imported(FromD, ToD);
- updateFlags(FromD, ToD);
- SavedImportPaths.erase(FromD);
- return ToDOrErr;
- }
- llvm::Expected<InheritedConstructor>
- ASTImporter::Import(const InheritedConstructor &From) {
- return ASTNodeImporter(*this).ImportInheritedConstructor(From);
- }
- 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())
- return ToDC;
- // If FromRecord is not defined we need to force it to be.
- // Simply calling CompleteDecl(...) for a RecordDecl will break some cases
- // it will start the definition but we never finish it.
- // If there are base classes they won't be imported and we will
- // be missing anything that we inherit from those bases.
- if (FromRecord->getASTContext().getExternalSource() &&
- !FromRecord->isCompleteDefinition())
- FromRecord->getASTContext().getExternalSource()->CompleteType(FromRecord);
- if (FromRecord->isCompleteDefinition())
- if (Error Err = ASTNodeImporter(*this).ImportDefinition(
- FromRecord, ToRecord, ASTNodeImporter::IDK_Basic))
- return std::move(Err);
- } 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->setDependence(FromE->getDependence());
- }
- // Record the imported statement object.
- ImportedStmts[FromS] = *ToSOrErr;
- return ToSOrErr;
- }
- Expected<NestedNameSpecifier *>
- ASTImporter::Import(NestedNameSpecifier *FromNNS) {
- if (!FromNNS)
- return nullptr;
- NestedNameSpecifier *Prefix = nullptr;
- 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 (ExpectedTypePtr TyOrErr = Import(FromNNS->getAsType())) {
- bool TSTemplate =
- FromNNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate;
- return NestedNameSpecifier::Create(ToContext, Prefix, TSTemplate,
- *TyOrErr);
- } 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);
- if (Kind == NestedNameSpecifier::TypeSpecWithTemplate)
- // ToLocalBeginLoc is here the location of the 'template' keyword.
- Builder.Extend(getToContext(), ToLocalBeginLoc, TSI->getTypeLoc(),
- ToLocalEndLoc);
- else
- // No location for 'template' keyword here.
- Builder.Extend(getToContext(), SourceLocation{}, 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 && !Cache->BufferOverridden) {
- // Include location of this file.
- ExpectedSLoc ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
- if (!ToIncludeLoc)
- return ToIncludeLoc.takeError();
- // Every FileID that is not the main FileID needs to have a valid include
- // location so that the include chain points to the main FileID. When
- // importing the main FileID (which has no include location), we need to
- // create a fake include location in the main file to keep this property
- // intact.
- SourceLocation ToIncludeLocOrFakeLoc = *ToIncludeLoc;
- if (FromID == FromSM.getMainFileID())
- ToIncludeLocOrFakeLoc = ToSM.getLocForStartOfFile(ToSM.getMainFileID());
- 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.
- auto Entry =
- ToFileManager.getOptionalFileRef(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, ToIncludeLocOrFakeLoc,
- FromSLoc.getFile().getFileCharacteristic());
- }
- }
- if (ToID.isInvalid() || IsBuiltin) {
- // FIXME: We want to re-use the existing MemoryBuffer!
- llvm::Optional<llvm::MemoryBufferRef> FromBuf =
- Cache->getBufferOrNone(FromContext.getDiagnostics(),
- FromSM.getFileManager(), SourceLocation{});
- if (!FromBuf)
- 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;
- }
- llvm::Expected<APValue> ASTImporter::Import(const APValue &FromValue) {
- ASTNodeImporter Importer(*this);
- return Importer.ImportAPValue(FromValue);
- }
- 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());
- }
- llvm::Expected<APValue>
- ASTNodeImporter::ImportAPValue(const APValue &FromValue) {
- APValue Result;
- llvm::Error Err = llvm::Error::success();
- auto ImportLoop = [&](const APValue *From, APValue *To, unsigned Size) {
- for (unsigned Idx = 0; Idx < Size; Idx++) {
- APValue Tmp = importChecked(Err, From[Idx]);
- To[Idx] = Tmp;
- }
- };
- switch (FromValue.getKind()) {
- case APValue::None:
- case APValue::Indeterminate:
- case APValue::Int:
- case APValue::Float:
- case APValue::FixedPoint:
- case APValue::ComplexInt:
- case APValue::ComplexFloat:
- Result = FromValue;
- break;
- case APValue::Vector: {
- Result.MakeVector();
- MutableArrayRef<APValue> Elts =
- Result.setVectorUninit(FromValue.getVectorLength());
- ImportLoop(((const APValue::Vec *)(const char *)&FromValue.Data)->Elts,
- Elts.data(), FromValue.getVectorLength());
- break;
- }
- case APValue::Array:
- Result.MakeArray(FromValue.getArrayInitializedElts(),
- FromValue.getArraySize());
- ImportLoop(((const APValue::Arr *)(const char *)&FromValue.Data)->Elts,
- ((const APValue::Arr *)(const char *)&Result.Data)->Elts,
- FromValue.getArrayInitializedElts());
- break;
- case APValue::Struct:
- Result.MakeStruct(FromValue.getStructNumBases(),
- FromValue.getStructNumFields());
- ImportLoop(
- ((const APValue::StructData *)(const char *)&FromValue.Data)->Elts,
- ((const APValue::StructData *)(const char *)&Result.Data)->Elts,
- FromValue.getStructNumBases() + FromValue.getStructNumFields());
- break;
- case APValue::Union: {
- Result.MakeUnion();
- const Decl *ImpFDecl = importChecked(Err, FromValue.getUnionField());
- APValue ImpValue = importChecked(Err, FromValue.getUnionValue());
- if (Err)
- return std::move(Err);
- Result.setUnion(cast<FieldDecl>(ImpFDecl), ImpValue);
- break;
- }
- case APValue::AddrLabelDiff: {
- Result.MakeAddrLabelDiff();
- const Expr *ImpLHS = importChecked(Err, FromValue.getAddrLabelDiffLHS());
- const Expr *ImpRHS = importChecked(Err, FromValue.getAddrLabelDiffRHS());
- if (Err)
- return std::move(Err);
- Result.setAddrLabelDiff(cast<AddrLabelExpr>(ImpLHS),
- cast<AddrLabelExpr>(ImpRHS));
- break;
- }
- case APValue::MemberPointer: {
- const Decl *ImpMemPtrDecl =
- importChecked(Err, FromValue.getMemberPointerDecl());
- if (Err)
- return std::move(Err);
- MutableArrayRef<const CXXRecordDecl *> ToPath =
- Result.setMemberPointerUninit(
- cast<const ValueDecl>(ImpMemPtrDecl),
- FromValue.isMemberPointerToDerivedMember(),
- FromValue.getMemberPointerPath().size());
- llvm::ArrayRef<const CXXRecordDecl *> FromPath =
- Result.getMemberPointerPath();
- for (unsigned Idx = 0; Idx < FromValue.getMemberPointerPath().size();
- Idx++) {
- const Decl *ImpDecl = importChecked(Err, FromPath[Idx]);
- if (Err)
- return std::move(Err);
- ToPath[Idx] = cast<const CXXRecordDecl>(ImpDecl->getCanonicalDecl());
- }
- break;
- }
- case APValue::LValue:
- APValue::LValueBase Base;
- QualType FromElemTy;
- if (FromValue.getLValueBase()) {
- assert(!FromValue.getLValueBase().is<DynamicAllocLValue>() &&
- "in C++20 dynamic allocation are transient so they shouldn't "
- "appear in the AST");
- if (!FromValue.getLValueBase().is<TypeInfoLValue>()) {
- if (const auto *E =
- FromValue.getLValueBase().dyn_cast<const Expr *>()) {
- FromElemTy = E->getType();
- const Expr *ImpExpr = importChecked(Err, E);
- if (Err)
- return std::move(Err);
- Base = APValue::LValueBase(ImpExpr,
- FromValue.getLValueBase().getCallIndex(),
- FromValue.getLValueBase().getVersion());
- } else {
- FromElemTy =
- FromValue.getLValueBase().get<const ValueDecl *>()->getType();
- const Decl *ImpDecl = importChecked(
- Err, FromValue.getLValueBase().get<const ValueDecl *>());
- if (Err)
- return std::move(Err);
- Base = APValue::LValueBase(cast<ValueDecl>(ImpDecl),
- FromValue.getLValueBase().getCallIndex(),
- FromValue.getLValueBase().getVersion());
- }
- } else {
- FromElemTy = FromValue.getLValueBase().getTypeInfoType();
- const Type *ImpTypeInfo = importChecked(
- Err, FromValue.getLValueBase().get<TypeInfoLValue>().getType());
- QualType ImpType =
- importChecked(Err, FromValue.getLValueBase().getTypeInfoType());
- if (Err)
- return std::move(Err);
- Base = APValue::LValueBase::getTypeInfo(TypeInfoLValue(ImpTypeInfo),
- ImpType);
- }
- }
- CharUnits Offset = FromValue.getLValueOffset();
- unsigned PathLength = FromValue.getLValuePath().size();
- Result.MakeLValue();
- if (FromValue.hasLValuePath()) {
- MutableArrayRef<APValue::LValuePathEntry> ToPath = Result.setLValueUninit(
- Base, Offset, PathLength, FromValue.isLValueOnePastTheEnd(),
- FromValue.isNullPointer());
- llvm::ArrayRef<APValue::LValuePathEntry> FromPath =
- FromValue.getLValuePath();
- for (unsigned LoopIdx = 0; LoopIdx < PathLength; LoopIdx++) {
- if (FromElemTy->isRecordType()) {
- const Decl *FromDecl =
- FromPath[LoopIdx].getAsBaseOrMember().getPointer();
- const Decl *ImpDecl = importChecked(Err, FromDecl);
- if (Err)
- return std::move(Err);
- if (auto *RD = dyn_cast<CXXRecordDecl>(FromDecl))
- FromElemTy = Importer.FromContext.getRecordType(RD);
- else
- FromElemTy = cast<ValueDecl>(FromDecl)->getType();
- ToPath[LoopIdx] = APValue::LValuePathEntry(APValue::BaseOrMemberType(
- ImpDecl, FromPath[LoopIdx].getAsBaseOrMember().getInt()));
- } else {
- FromElemTy =
- Importer.FromContext.getAsArrayType(FromElemTy)->getElementType();
- ToPath[LoopIdx] = APValue::LValuePathEntry::ArrayIndex(
- FromPath[LoopIdx].getAsArrayIndex());
- }
- }
- } else
- Result.setLValue(Base, Offset, APValue::NoLValuePath{},
- FromValue.isNullPointer());
- }
- if (Err)
- return std::move(Err);
- return Result;
- }
- Expected<DeclarationName> ASTImporter::HandleNameConflict(DeclarationName Name,
- DeclContext *DC,
- unsigned IDNS,
- NamedDecl **Decls,
- unsigned NumDecls) {
- if (ODRHandling == ODRHandlingType::Conservative)
- // Report error at any name conflict.
- return make_error<ImportError>(ImportError::NameConflict);
- else
- // Allow to create the new Decl with the same name.
- 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;
- // In the case of TypedefNameDecl we create the Decl first and only then we
- // import and set its DeclContext. So, the DC is still not set when we reach
- // here from GetImportedOrCreateDecl.
- if (To->getDeclContext())
- AddToLookupTable(To);
- return To;
- }
- llvm::Optional<ImportError>
- ASTImporter::getImportDeclErrorIfAny(Decl *FromD) const {
- auto Pos = ImportDeclErrors.find(FromD);
- if (Pos != ImportDeclErrors.end())
- return Pos->second;
- else
- return Optional<ImportError>();
- }
- void ASTImporter::setImportDeclError(Decl *From, ImportError Error) {
- auto InsertRes = ImportDeclErrors.insert({From, Error});
- (void)InsertRes;
- // Either we set the error for the first time, or we already had set one and
- // now we want to set the same error.
- assert(InsertRes.second || InsertRes.first->second.Error == Error.Error);
- }
- 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);
- }
|