1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070 |
- //===- 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/ASTContext.h"
- #include "clang/AST/ASTDiagnostic.h"
- #include "clang/AST/ASTImporterSharedState.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/STLExtras.h"
- #include "llvm/ADT/ScopeExit.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 <optional>
- #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 ASTImportError::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 ASTImportError::log(raw_ostream &OS) const { OS << toString(); }
- std::error_code ASTImportError::convertToErrorCode() const {
- llvm_unreachable("Function not implemented.");
- }
- char ASTImportError::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();
- }
- /// How to handle import errors that occur when import of a child declaration
- /// of a DeclContext fails.
- class ChildErrorHandlingStrategy {
- /// This context is imported (in the 'from' domain).
- /// It is nullptr if a non-DeclContext is imported.
- const DeclContext *const FromDC;
- /// Ignore import errors of the children.
- /// If true, the context can be imported successfully if a child
- /// of it failed to import. Otherwise the import errors of the child nodes
- /// are accumulated (joined) into the import error object of the parent.
- /// (Import of a parent can fail in other ways.)
- bool const IgnoreChildErrors;
- public:
- ChildErrorHandlingStrategy(const DeclContext *FromDC)
- : FromDC(FromDC), IgnoreChildErrors(!isa<TagDecl>(FromDC)) {}
- ChildErrorHandlingStrategy(const Decl *FromD)
- : FromDC(dyn_cast<DeclContext>(FromD)),
- IgnoreChildErrors(!isa<TagDecl>(FromD)) {}
- /// Process the import result of a child (of the current declaration).
- /// \param ResultErr The import error that can be used as result of
- /// importing the parent. This may be changed by the function.
- /// \param ChildErr Result of importing a child. Can be success or error.
- void handleChildImportResult(Error &ResultErr, Error &&ChildErr) {
- if (ChildErr && !IgnoreChildErrors)
- ResultErr = joinErrors(std::move(ResultErr), std::move(ChildErr));
- else
- consumeError(std::move(ChildErr));
- }
- /// Determine if import failure of a child does not cause import failure of
- /// its parent.
- bool ignoreChildErrorOnParent(Decl *FromChildD) const {
- if (!IgnoreChildErrors || !FromDC)
- return false;
- return FromDC->containsDecl(FromChildD);
- }
- };
- 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>
- [[nodiscard]] Error importInto(ImportT &To, const ImportT &From) {
- return Importer.importInto(To, From);
- }
- // Use this to import pointers of specific type.
- template <typename ImportT>
- [[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_v<Type, T>, 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 std::optional<T> by importing the contained T, if any.
- template <typename T>
- Expected<std::optional<T>> import(std::optional<T> From) {
- if (!From)
- return std::nullopt;
- 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>
- [[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>
- [[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>
- [[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);
- Importer.SharedState->markAsNewDecl(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(ArrayRef<TemplateArgument> FromArgs,
- 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 VisitUsingPackDecl(UsingPackDecl *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.
- if (Error Err = ImportTemplateArguments(FTSInfo->TemplateArguments->asArray(),
- 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_elements(), ToPack))
- return std::move(Err);
- return TemplateArgument(
- llvm::ArrayRef(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) {
- ValueDecl *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<ASTImportError>(ASTImportError::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();
- ExpectedType ToUnderlyingTypeOrErr = import(T->desugar());
- if (!ToUnderlyingTypeOrErr)
- return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getTypedefType(*ToDeclOrErr,
- *ToUnderlyingTypeOrErr);
- }
- ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
- ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
- if (!ToExprOrErr)
- return ToExprOrErr.takeError();
- return Importer.getToContext().getTypeOfExprType(*ToExprOrErr, T->getKind());
- }
- ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
- ExpectedType ToUnderlyingTypeOrErr = import(T->getUnmodifiedType());
- if (!ToUnderlyingTypeOrErr)
- return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr,
- T->getKind());
- }
- 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;
- if (Error Err = ImportTemplateArguments(T->getTypeConstraintArguments(),
- 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<Decl *> ReplacedOrErr = import(T->getAssociatedDecl());
- if (!ReplacedOrErr)
- return ReplacedOrErr.takeError();
- ExpectedType ToReplacementTypeOrErr = import(T->getReplacementType());
- if (!ToReplacementTypeOrErr)
- return ToReplacementTypeOrErr.takeError();
- return Importer.getToContext().getSubstTemplateTypeParmType(
- *ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(),
- T->getPackIndex());
- }
- ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
- const SubstTemplateTypeParmPackType *T) {
- Expected<Decl *> ReplacedOrErr = import(T->getAssociatedDecl());
- if (!ReplacedOrErr)
- return ReplacedOrErr.takeError();
- Expected<TemplateArgument> ToArgumentPack = import(T->getArgumentPack());
- if (!ToArgumentPack)
- return ToArgumentPack.takeError();
- return Importer.getToContext().getSubstTemplateTypeParmPackType(
- *ReplacedOrErr, T->getIndex(), T->getFinal(), *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->template_arguments(), 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->template_arguments().size());
- if (Error Err = ImportTemplateArguments(T->template_arguments(), 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<ASTImportError>(ASTImportError::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.
- ChildErrorHandlingStrategy HandleChildErrors(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);
- HandleChildErrors.handleChildImportResult(ChildErrors,
- std::move(Err));
- }
- }
- }
- } else {
- HandleChildErrors.handleChildImportResult(ChildErrors,
- 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();
- // Set the definition to complete even if it is really not complete during
- // import. Some AST constructs (expressions) require the record layout
- // to be calculated (see 'clang::computeDependence') at the time they are
- // constructed. Import of such AST node is possible during import of the
- // same record, there is no way to have a completely defined record (all
- // fields imported) at that time without multiple AST import passes.
- if (!Importer.isMinimalImport())
- To->setCompleteDefinition(true);
- // 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(
- ArrayRef<TemplateArgument> FromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs) {
- for (const auto &Arg : FromArgs) {
- if (auto ToOrErr = import(Arg))
- 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<ASTImportError>(ASTImportError::UnsupportedConstruct);
- }
- ExpectedDecl ASTNodeImporter::VisitImportDecl(ImportDecl *D) {
- Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
- << D->getDeclKindName();
- return make_error<ASTImportError>(ASTImportError::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, D->isNested()))
- 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->getLambdaDependencyKind(),
- 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_DependentNonTemplate:
- if (Expected<FunctionDecl *> InstFDOrErr =
- import(FromFD->getInstantiatedFromDecl()))
- ToFD->setInstantiatedFromDecl(*InstFDOrErr);
- 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::ArrayRef(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, or D is equal to DC.
- static bool isAncestorDeclContextOf(const DeclContext *DC, const Decl *D) {
- const DeclContext *DCi = dyn_cast<DeclContext>(D);
- if (!DCi)
- DCi = D->getDeclContext();
- assert(DCi && "Declaration should have a context");
- while (DCi != D->getTranslationUnitDecl()) {
- if (DCi == DC)
- return true;
- DCi = DCi->getParent();
- }
- return false;
- }
- // Check if there is a declaration that has 'DC' as parent context and is
- // referenced from statement 'S' or one of its children. The search is done in
- // BFS order through children of 'S'.
- static bool isAncestorDeclContextOf(const DeclContext *DC, const Stmt *S) {
- SmallVector<const Stmt *> ToProcess;
- ToProcess.push_back(S);
- while (!ToProcess.empty()) {
- const Stmt *CurrentS = ToProcess.pop_back_val();
- ToProcess.append(CurrentS->child_begin(), CurrentS->child_end());
- if (const auto *DeclRef = dyn_cast<DeclRefExpr>(CurrentS))
- if (const Decl *D = DeclRef->getDecl())
- if (isAncestorDeclContextOf(DC, D))
- return true;
- }
- return false;
- }
- namespace {
- /// Check if a type has any reference to a declaration that is inside the body
- /// of a function.
- /// The \c CheckType(QualType) function should be used to determine
- /// this property.
- ///
- /// The type visitor visits one type object only (not recursive).
- /// To find all referenced declarations we must discover all type objects until
- /// the canonical type is reached (walk over typedef and similar objects). This
- /// is done by loop over all "sugar" type objects. For every such type we must
- /// check all declarations that are referenced from it. For this check the
- /// visitor is used. In the visit functions all referenced declarations except
- /// the one that follows in the sugar chain (if any) must be checked. For this
- /// check the same visitor is re-used (it has no state-dependent data).
- ///
- /// The visit functions have 3 possible return values:
- /// - True, found a declaration inside \c ParentDC.
- /// - False, found declarations only outside \c ParentDC and it is not possible
- /// to find more declarations (the "sugar" chain does not continue).
- /// - Empty optional value, found no declarations or only outside \c ParentDC,
- /// but it is possible to find more declarations in the type "sugar" chain.
- /// The loop over the "sugar" types can be implemented by using type visit
- /// functions only (call \c CheckType with the desugared type). With the current
- /// solution no visit function is needed if the type has only a desugared type
- /// as data.
- class IsTypeDeclaredInsideVisitor
- : public TypeVisitor<IsTypeDeclaredInsideVisitor, std::optional<bool>> {
- public:
- IsTypeDeclaredInsideVisitor(const FunctionDecl *ParentDC)
- : ParentDC(ParentDC) {}
- bool CheckType(QualType T) {
- // Check the chain of "sugar" types.
- // The "sugar" types are typedef or similar types that have the same
- // canonical type.
- if (std::optional<bool> Res = Visit(T.getTypePtr()))
- return *Res;
- QualType DsT =
- T.getSingleStepDesugaredType(ParentDC->getParentASTContext());
- while (DsT != T) {
- if (std::optional<bool> Res = Visit(DsT.getTypePtr()))
- return *Res;
- T = DsT;
- DsT = T.getSingleStepDesugaredType(ParentDC->getParentASTContext());
- }
- return false;
- }
- std::optional<bool> VisitTagType(const TagType *T) {
- if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
- for (const auto &Arg : Spec->getTemplateArgs().asArray())
- if (checkTemplateArgument(Arg))
- return true;
- return isAncestorDeclContextOf(ParentDC, T->getDecl());
- }
- std::optional<bool> VisitPointerType(const PointerType *T) {
- return CheckType(T->getPointeeType());
- }
- std::optional<bool> VisitReferenceType(const ReferenceType *T) {
- return CheckType(T->getPointeeTypeAsWritten());
- }
- std::optional<bool> VisitTypedefType(const TypedefType *T) {
- const TypedefNameDecl *TD = T->getDecl();
- assert(TD);
- return isAncestorDeclContextOf(ParentDC, TD);
- }
- std::optional<bool> VisitUsingType(const UsingType *T) {
- if (T->getFoundDecl() &&
- isAncestorDeclContextOf(ParentDC, T->getFoundDecl()))
- return true;
- return {};
- }
- std::optional<bool>
- VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- for (const auto &Arg : T->template_arguments())
- if (checkTemplateArgument(Arg))
- return true;
- // This type is a "sugar" to a record type, it can have a desugared type.
- return {};
- }
- std::optional<bool> VisitConstantArrayType(const ConstantArrayType *T) {
- if (T->getSizeExpr() && isAncestorDeclContextOf(ParentDC, T->getSizeExpr()))
- return true;
- return CheckType(T->getElementType());
- }
- std::optional<bool> VisitVariableArrayType(const VariableArrayType *T) {
- llvm_unreachable(
- "Variable array should not occur in deduced return type of a function");
- }
- std::optional<bool> VisitIncompleteArrayType(const IncompleteArrayType *T) {
- llvm_unreachable("Incomplete array should not occur in deduced return type "
- "of a function");
- }
- std::optional<bool> VisitDependentArrayType(const IncompleteArrayType *T) {
- llvm_unreachable("Dependent array should not occur in deduced return type "
- "of a function");
- }
- private:
- const DeclContext *const ParentDC;
- bool checkTemplateArgument(const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- return false;
- case TemplateArgument::Integral:
- return CheckType(Arg.getIntegralType());
- case TemplateArgument::Type:
- return CheckType(Arg.getAsType());
- case TemplateArgument::Expression:
- return isAncestorDeclContextOf(ParentDC, Arg.getAsExpr());
- case TemplateArgument::Declaration:
- // FIXME: The declaration in this case is not allowed to be in a function?
- return isAncestorDeclContextOf(ParentDC, Arg.getAsDecl());
- case TemplateArgument::NullPtr:
- // FIXME: The type is not allowed to be in the function?
- return CheckType(Arg.getNullPtrType());
- case TemplateArgument::Pack:
- for (const auto &PackArg : Arg.getPackAsArray())
- if (checkTemplateArgument(PackArg))
- return true;
- return false;
- case TemplateArgument::Template:
- // Templates can not be defined locally in functions.
- // A template passed as argument can be not in ParentDC.
- return false;
- case TemplateArgument::TemplateExpansion:
- // Templates can not be defined locally in functions.
- // A template passed as argument can be not in ParentDC.
- return false;
- }
- llvm_unreachable("Unknown TemplateArgument::ArgKind enum");
- };
- };
- } // namespace
- bool ASTNodeImporter::hasAutoReturnTypeDeclaredInside(FunctionDecl *D) {
- QualType FromTy = D->getType();
- const auto *FromFPT = FromTy->getAs<FunctionProtoType>();
- assert(FromFPT && "Must be called on FunctionProtoType");
- QualType RetT = FromFPT->getReturnType();
- if (isa<AutoType>(RetT.getTypePtr())) {
- FunctionDecl *Def = D->getDefinition();
- IsTypeDeclaredInsideVisitor Visitor(Def ? Def : D);
- return Visitor.CheckType(RetT);
- }
- 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 ToDefaultLoc = importChecked(Err, D->getDefaultLoc());
- 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->setFriendConstraintRefersToEnclosingTemplate(
- D->FriendConstraintRefersToEnclosingTemplate());
- ToFunction->setRangeEnd(ToEndLoc);
- ToFunction->setDefaultLoc(ToDefaultLoc);
- // 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 it is a template, import all related things.
- if (Error Err = ImportTemplateInformation(D, ToFunction))
- return std::move(Err);
- 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?
- 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.
- // Note: `hasInClassInitializer()` is not the same as non-null
- // `getInClassInitializer()` value.
- if (Expr *FromInitializer = D->getInClassInitializer()) {
- if (ExpectedExpr ToInitializerOrErr = import(FromInitializer)) {
- // Import of the FromInitializer may result in the setting of
- // InClassInitializer. If not, set it here.
- assert(FoundField->hasInClassInitializer() &&
- "Field should have an in-class initializer if it has an "
- "expression for it.");
- if (!FoundField->getInClassInitializer())
- FoundField->setInClassInitializer(*ToInitializerOrErr);
- } else {
- return ToInitializerOrErr.takeError();
- }
- }
- 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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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;
- std::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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 ToNameLoc = importChecked(Err, D->getLocation());
- auto *ToEnumType = importChecked(Err, D->getEnumType());
- if (Err)
- return std::move(Err);
- UsingEnumDecl *ToUsingEnum;
- if (GetImportedOrCreateDecl(ToUsingEnum, D, Importer.getToContext(), DC,
- ToUsingLoc, ToEnumLoc, ToNameLoc, ToEnumType))
- 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::VisitUsingPackDecl(UsingPackDecl *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 ToInstantiatedFromUsingOrErr =
- Importer.Import(D->getInstantiatedFromUsingDecl());
- if (!ToInstantiatedFromUsingOrErr)
- return ToInstantiatedFromUsingOrErr.takeError();
- SmallVector<NamedDecl *, 4> Expansions(D->expansions().size());
- if (Error Err = ImportArrayChecked(D->expansions(), Expansions.begin()))
- return std::move(Err);
- UsingPackDecl *ToUsingPack;
- if (GetImportedOrCreateDecl(ToUsingPack, D, Importer.getToContext(), DC,
- cast<NamedDecl>(*ToInstantiatedFromUsingOrErr),
- Expansions))
- return ToUsingPack;
- addDeclToContexts(D, ToUsingPack);
- return ToUsingPack;
- }
- 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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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<ASTImportError>(ASTImportError::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);
- }
- 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().asArray(), 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<ASTImportError>(ASTImportError::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::ArrayRef(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 (auto P = D->getInstantiatedFrom()) {
- if (auto *CTD = P.dyn_cast<ClassTemplateDecl *>()) {
- if (auto CTDorErr = import(CTD))
- D2->setInstantiationOf(*CTDorErr);
- } else {
- auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl *>(P);
- auto CTPSDOrErr = import(CTPSD);
- if (!CTPSDOrErr)
- return CTPSDOrErr.takeError();
- const TemplateArgumentList &DArgs = D->getTemplateInstantiationArgs();
- SmallVector<TemplateArgument, 2> D2ArgsVec(DArgs.size());
- for (unsigned I = 0; I < DArgs.size(); ++I) {
- const TemplateArgument &DArg = DArgs[I];
- if (auto ArgOrErr = import(DArg))
- D2ArgsVec[I] = *ArgOrErr;
- else
- return ArgOrErr.takeError();
- }
- D2->setInstantiationOf(
- *CTPSDOrErr,
- TemplateArgumentList::CreateCopy(Importer.getToContext(), D2ArgsVec));
- }
- }
- 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);
- }
- 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().asArray(), 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 {
- TemplateArgumentListInfo ToTAInfo;
- if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
- if (Error Err = ImportTemplateArgumentListInfo(*Args, 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, QualType(), nullptr,
- 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,
- QualType(), nullptr, D->getStorageClass(),
- TemplateArgs))
- return D2;
- }
- QualType T;
- if (Error Err = importInto(T, D->getType()))
- return std::move(Err);
- D2->setType(T);
- auto TInfoOrErr = import(D->getTypeSourceInfo());
- if (!TInfoOrErr)
- return TInfoOrErr.takeError();
- D2->setTypeSourceInfo(*TInfoOrErr);
- 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<ASTImportError>(ASTImportError::UnsupportedConstruct);
- }
- ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
- if (Importer.returnWithErrorInTest())
- return make_error<ASTImportError>(ASTImportError::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();
- FPOptionsOverride FPO =
- S->hasStoredFPFeatures() ? S->getStoredFPFeatures() : FPOptionsOverride();
- return CompoundStmt::Create(Importer.getToContext(), ToStmts, FPO,
- *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<ASTImportError>(ASTImportError::UnsupportedConstruct);
- }
- ExpectedStmt ASTNodeImporter::VisitSourceLocExpr(SourceLocExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- 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(), ToType, 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::ArrayRef(ToAssocTypes),
- llvm::ArrayRef(ToAssocExprs), ToDefaultLoc, ToRParenLoc,
- E->containsUnexpandedParameterPack());
- }
- return GenericSelectionExpr::Create(
- ToCtx, ToGenericLoc, ToControllingExpr, llvm::ArrayRef(ToAssocTypes),
- llvm::ArrayRef(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());
- }
- 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(),
- 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<ASTImportError>(ASTImportError::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()) {
- std::optional<ParmVarDecl *> FromParam =
- Importer.getImportedFromDecl(ToParam);
- assert(FromParam && "ParmVarDecl was not imported?");
- if (Error Err = ImportDefaultArgOfParmVarDecl(*FromParam, ToParam))
- return std::move(Err);
- }
- Expr *RewrittenInit = nullptr;
- if (E->hasRewrittenInit()) {
- ExpectedExpr ExprOrErr = import(E->getRewrittenExpr());
- if (!ExprOrErr)
- return ExprOrErr.takeError();
- RewrittenInit = ExprOrErr.get();
- }
- return CXXDefaultArgExpr::Create(Importer.getToContext(), *ToUsedLocOrErr,
- *ToParamOrErr, RewrittenInit,
- *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);
- std::optional<unsigned> Length;
- if (!E->isValueDependent())
- Length = E->getPackLength();
- SmallVector<TemplateArgument, 8> ToPartialArguments;
- if (E->isPartiallySubstituted()) {
- if (Error Err = ImportTemplateArguments(E->getPartialArguments(),
- 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 CXXBoolLiteralExpr::Create(Importer.getToContext(), 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::ArrayRef(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();
- FieldDecl *ToField = *ToFieldOrErr;
- assert(ToField->hasInClassInitializer() &&
- "Field should have in-class initializer if there is a default init "
- "expression that uses it.");
- if (!ToField->getInClassInitializer()) {
- // The in-class initializer may be not yet set in "To" AST even if the
- // field is already there. This must be set here to make construction of
- // CXXDefaultInitExpr work.
- auto ToInClassInitializerOrErr =
- import(E->getField()->getInClassInitializer());
- if (!ToInClassInitializerOrErr)
- return ToInClassInitializerOrErr.takeError();
- ToField->setInClassInitializer(*ToInClassInitializerOrErr);
- }
- Expr *RewrittenInit = nullptr;
- if (E->hasRewrittenInit()) {
- ExpectedExpr ExprOrErr = import(E->getRewrittenExpr());
- if (!ExprOrErr)
- return ExprOrErr.takeError();
- RewrittenInit = ExprOrErr.get();
- }
- return CXXDefaultInitExpr::Create(Importer.getToContext(), *ToBeginLocOrErr,
- ToField, *UsedContextOrErr, RewrittenInit);
- }
- 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<ASTImportError>();
- }
- }
- ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
- SubstNonTypeTemplateParmExpr *E) {
- Error Err = Error::success();
- auto ToType = importChecked(Err, E->getType());
- auto ToExprLoc = importChecked(Err, E->getExprLoc());
- auto ToAssociatedDecl = importChecked(Err, E->getAssociatedDecl());
- auto ToReplacement = importChecked(Err, E->getReplacement());
- if (Err)
- return std::move(Err);
- return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
- ToType, E->getValueKind(), ToExprLoc, ToReplacement, ToAssociatedDecl,
- E->getIndex(), E->getPackIndex(), E->isReferenceParameter());
- }
- 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;
- std::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 std::nullopt;
- 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 std::nullopt;
- }
- 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<ASTImportError>(ASTImportError::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);
- }
- namespace {
- // 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;
- }
- };
- } // namespace
- 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::EnableIf: {
- const auto *From = cast<EnableIfAttr>(FromAttr);
- AI.importAttr(From, AI.importArg(From->getCond()).value(),
- From->getMessage());
- 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<ASTImportError>(*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<ASTImportError>(*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?).
- ASTImportError ErrOut;
- handleAllErrors(ToDOrErr.takeError(),
- [&ErrOut](const ASTImportError &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]) {
- // The import path contains import-dependency nodes first.
- // Save the node that was imported as dependency of the current node.
- Decl *PrevFromDi = FromD;
- for (Decl *FromDi : Path) {
- // Begin and end of the path equals 'FromD', skip it.
- if (FromDi == FromD)
- continue;
- // We should not set import error on a node and all following nodes in
- // the path if child import errors are ignored.
- if (ChildErrorHandlingStrategy(FromDi).ignoreChildErrorOnParent(
- PrevFromDi))
- break;
- PrevFromDi = FromDi;
- 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<ASTImportError>(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<ASTImportError>(*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<ASTImportError>(*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();
- auto TNOrErr = Import(QTN->getUnderlyingTemplate());
- if (!TNOrErr)
- return TNOrErr.takeError();
- return ToContext.getQualifiedTemplateName(
- *QualifierOrErr, QTN->hasTemplateKeyword(), *TNOrErr);
- }
- 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();
- auto ReplacementOrErr = Import(Subst->getReplacement());
- if (!ReplacementOrErr)
- return ReplacementOrErr.takeError();
- auto AssociatedDeclOrErr = Import(Subst->getAssociatedDecl());
- if (!AssociatedDeclOrErr)
- return AssociatedDeclOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParm(
- *ReplacementOrErr, *AssociatedDeclOrErr, Subst->getIndex(),
- Subst->getPackIndex());
- }
- case TemplateName::SubstTemplateTemplateParmPack: {
- SubstTemplateTemplateParmPackStorage *SubstPack =
- From.getAsSubstTemplateTemplateParmPack();
- ASTNodeImporter Importer(*this);
- auto ArgPackOrErr =
- Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
- if (!ArgPackOrErr)
- return ArgPackOrErr.takeError();
- auto AssociatedDeclOrErr = Import(SubstPack->getAssociatedDecl());
- if (!AssociatedDeclOrErr)
- return AssociatedDeclOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParmPack(
- *ArgPackOrErr, *AssociatedDeclOrErr, SubstPack->getIndex(),
- SubstPack->getFinal());
- }
- case TemplateName::UsingTemplate: {
- auto UsingOrError = Import(From.getAsUsingShadowDecl());
- if (!UsingOrError)
- return UsingOrError.takeError();
- return TemplateName(cast<UsingShadowDecl>(*UsingOrError));
- }
- }
- 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 ExLength = FromSM.getFileIDSize(FromID);
- SourceLocation MLoc;
- if (FromEx.isMacroArgExpansion()) {
- MLoc = ToSM.createMacroArgExpansionLoc(*ToSpLoc, *ToExLocS, ExLength);
- } else {
- if (ExpectedSLoc ToExLocE = Import(FromEx.getExpansionLocEnd()))
- MLoc = ToSM.createExpansionLoc(*ToSpLoc, *ToExLocS, *ToExLocE, ExLength,
- 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!
- std::optional<llvm::MemoryBufferRef> FromBuf =
- Cache->getBufferOrNone(FromContext.getDiagnostics(),
- FromSM.getFileManager(), SourceLocation{});
- if (!FromBuf)
- return llvm::make_error<ASTImportError>(ASTImportError::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<ASTImportError>();
- }
- }
- 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<ASTImportError>(ASTImportError::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;
- }
- std::optional<ASTImportError>
- ASTImporter::getImportDeclErrorIfAny(Decl *FromD) const {
- auto Pos = ImportDeclErrors.find(FromD);
- if (Pos != ImportDeclErrors.end())
- return Pos->second;
- else
- return std::nullopt;
- }
- void ASTImporter::setImportDeclError(Decl *From, ASTImportError 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);
- }
|