12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969 |
- //===--- Tools.cpp - Tools Implementations --------------------------------===//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "Tools.h"
- #include "InputInfo.h"
- #include "SanitizerArgs.h"
- #include "ToolChains.h"
- #include "clang/Basic/ObjCRuntime.h"
- #include "clang/Driver/Action.h"
- #include "clang/Driver/Arg.h"
- #include "clang/Driver/ArgList.h"
- #include "clang/Driver/Compilation.h"
- #include "clang/Driver/Driver.h"
- #include "clang/Driver/DriverDiagnostic.h"
- #include "clang/Driver/Job.h"
- #include "clang/Driver/Option.h"
- #include "clang/Driver/Options.h"
- #include "clang/Driver/ToolChain.h"
- #include "clang/Driver/Util.h"
- #include "llvm/ADT/SmallString.h"
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/ADT/Twine.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/Format.h"
- #include "llvm/Support/Host.h"
- #include "llvm/Support/Process.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace clang::driver;
- using namespace clang::driver::tools;
- using namespace clang;
- /// CheckPreprocessingOptions - Perform some validation of preprocessing
- /// arguments that is shared with gcc.
- static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
- if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
- if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP)
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "-E";
- }
- /// CheckCodeGenerationOptions - Perform some validation of code generation
- /// arguments that is shared with gcc.
- static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
- // In gcc, only ARM checks this, but it seems reasonable to check universally.
- if (Args.hasArg(options::OPT_static))
- if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
- options::OPT_mdynamic_no_pic))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << A->getAsString(Args) << "-static";
- }
- // Quote target names for inclusion in GNU Make dependency files.
- // Only the characters '$', '#', ' ', '\t' are quoted.
- static void QuoteTarget(StringRef Target,
- SmallVectorImpl<char> &Res) {
- for (unsigned i = 0, e = Target.size(); i != e; ++i) {
- switch (Target[i]) {
- case ' ':
- case '\t':
- // Escape the preceding backslashes
- for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
- Res.push_back('\\');
- // Escape the space/tab
- Res.push_back('\\');
- break;
- case '$':
- Res.push_back('$');
- break;
- case '#':
- Res.push_back('\\');
- break;
- default:
- break;
- }
- Res.push_back(Target[i]);
- }
- }
- static void addDirectoryList(const ArgList &Args,
- ArgStringList &CmdArgs,
- const char *ArgName,
- const char *EnvVar) {
- const char *DirList = ::getenv(EnvVar);
- bool CombinedArg = false;
- if (!DirList)
- return; // Nothing to do.
- StringRef Name(ArgName);
- if (Name.equals("-I") || Name.equals("-L"))
- CombinedArg = true;
- StringRef Dirs(DirList);
- if (Dirs.empty()) // Empty string should not add '.'.
- return;
- StringRef::size_type Delim;
- while ((Delim = Dirs.find(llvm::sys::PathSeparator)) != StringRef::npos) {
- if (Delim == 0) { // Leading colon.
- if (CombinedArg) {
- CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
- } else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
- }
- } else {
- if (CombinedArg) {
- CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
- } else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
- }
- }
- Dirs = Dirs.substr(Delim + 1);
- }
- if (Dirs.empty()) { // Trailing colon.
- if (CombinedArg) {
- CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
- } else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
- }
- } else { // Add the last path.
- if (CombinedArg) {
- CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
- } else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs));
- }
- }
- }
- static void AddLinkerInputs(const ToolChain &TC,
- const InputInfoList &Inputs, const ArgList &Args,
- ArgStringList &CmdArgs) {
- const Driver &D = TC.getDriver();
- // Add extra linker input arguments which are not treated as inputs
- // (constructed via -Xarch_).
- Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- if (!TC.HasNativeLLVMSupport()) {
- // Don't try to pass LLVM inputs unless we have native support.
- if (II.getType() == types::TY_LLVM_IR ||
- II.getType() == types::TY_LTO_IR ||
- II.getType() == types::TY_LLVM_BC ||
- II.getType() == types::TY_LTO_BC)
- D.Diag(diag::err_drv_no_linker_llvm_support)
- << TC.getTripleString();
- }
- // Add filenames immediately.
- if (II.isFilename()) {
- CmdArgs.push_back(II.getFilename());
- continue;
- }
- // Otherwise, this is a linker input argument.
- const Arg &A = II.getInputArg();
- // Handle reserved library options.
- if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
- TC.AddCXXStdlibLibArgs(Args, CmdArgs);
- } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
- TC.AddCCKextLibArgs(Args, CmdArgs);
- } else
- A.renderAsInput(Args, CmdArgs);
- }
- // LIBRARY_PATH - included following the user specified library paths.
- addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
- }
- /// \brief Determine whether Objective-C automated reference counting is
- /// enabled.
- static bool isObjCAutoRefCount(const ArgList &Args) {
- return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
- }
- /// \brief Determine whether we are linking the ObjC runtime.
- static bool isObjCRuntimeLinked(const ArgList &Args) {
- if (isObjCAutoRefCount(Args)) {
- Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
- return true;
- }
- return Args.hasArg(options::OPT_fobjc_link_runtime);
- }
- static void addProfileRT(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs,
- llvm::Triple Triple) {
- if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
- Args.hasArg(options::OPT_fprofile_generate) ||
- Args.hasArg(options::OPT_fcreate_profile) ||
- Args.hasArg(options::OPT_coverage)))
- return;
- // GCC links libgcov.a by adding -L<inst>/gcc/lib/gcc/<triple>/<ver> -lgcov to
- // the link line. We cannot do the same thing because unlike gcov there is a
- // libprofile_rt.so. We used to use the -l:libprofile_rt.a syntax, but that is
- // not supported by old linkers.
- std::string ProfileRT =
- std::string(TC.getDriver().Dir) + "/../lib/libprofile_rt.a";
- CmdArgs.push_back(Args.MakeArgString(ProfileRT));
- }
- static bool forwardToGCC(const Option &O) {
- return !O.hasFlag(options::NoForward) &&
- !O.hasFlag(options::DriverOption) &&
- !O.hasFlag(options::LinkerInput);
- }
- void Clang::AddPreprocessingOptions(Compilation &C,
- const Driver &D,
- const ArgList &Args,
- ArgStringList &CmdArgs,
- const InputInfo &Output,
- const InputInfoList &Inputs) const {
- Arg *A;
- CheckPreprocessingOptions(D, Args);
- Args.AddLastArg(CmdArgs, options::OPT_C);
- Args.AddLastArg(CmdArgs, options::OPT_CC);
- // Handle dependency file generation.
- if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
- (A = Args.getLastArg(options::OPT_MD)) ||
- (A = Args.getLastArg(options::OPT_MMD))) {
- // Determine the output location.
- const char *DepFile;
- if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
- DepFile = MF->getValue();
- C.addFailureResultFile(DepFile);
- } else if (Output.getType() == types::TY_Dependencies) {
- DepFile = Output.getFilename();
- } else if (A->getOption().matches(options::OPT_M) ||
- A->getOption().matches(options::OPT_MM)) {
- DepFile = "-";
- } else {
- DepFile = getDependencyFileName(Args, Inputs);
- C.addFailureResultFile(DepFile);
- }
- CmdArgs.push_back("-dependency-file");
- CmdArgs.push_back(DepFile);
- // Add a default target if one wasn't specified.
- if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
- const char *DepTarget;
- // If user provided -o, that is the dependency target, except
- // when we are only generating a dependency file.
- Arg *OutputOpt = Args.getLastArg(options::OPT_o);
- if (OutputOpt && Output.getType() != types::TY_Dependencies) {
- DepTarget = OutputOpt->getValue();
- } else {
- // Otherwise derive from the base input.
- //
- // FIXME: This should use the computed output file location.
- SmallString<128> P(Inputs[0].getBaseInput());
- llvm::sys::path::replace_extension(P, "o");
- DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
- }
- CmdArgs.push_back("-MT");
- SmallString<128> Quoted;
- QuoteTarget(DepTarget, Quoted);
- CmdArgs.push_back(Args.MakeArgString(Quoted));
- }
- if (A->getOption().matches(options::OPT_M) ||
- A->getOption().matches(options::OPT_MD))
- CmdArgs.push_back("-sys-header-deps");
- }
- if (Args.hasArg(options::OPT_MG)) {
- if (!A || A->getOption().matches(options::OPT_MD) ||
- A->getOption().matches(options::OPT_MMD))
- D.Diag(diag::err_drv_mg_requires_m_or_mm);
- CmdArgs.push_back("-MG");
- }
- Args.AddLastArg(CmdArgs, options::OPT_MP);
- // Convert all -MQ <target> args to -MT <quoted target>
- for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
- options::OPT_MQ),
- ie = Args.filtered_end(); it != ie; ++it) {
- const Arg *A = *it;
- A->claim();
- if (A->getOption().matches(options::OPT_MQ)) {
- CmdArgs.push_back("-MT");
- SmallString<128> Quoted;
- QuoteTarget(A->getValue(), Quoted);
- CmdArgs.push_back(Args.MakeArgString(Quoted));
- // -MT flag - no change
- } else {
- A->render(Args, CmdArgs);
- }
- }
- // Add -i* options, and automatically translate to
- // -include-pch/-include-pth for transparent PCH support. It's
- // wonky, but we include looking for .gch so we can support seamless
- // replacement into a build system already set up to be generating
- // .gch files.
- bool RenderedImplicitInclude = false;
- for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
- ie = Args.filtered_end(); it != ie; ++it) {
- const Arg *A = it;
- if (A->getOption().matches(options::OPT_include)) {
- bool IsFirstImplicitInclude = !RenderedImplicitInclude;
- RenderedImplicitInclude = true;
- // Use PCH if the user requested it.
- bool UsePCH = D.CCCUsePCH;
- bool FoundPTH = false;
- bool FoundPCH = false;
- llvm::sys::Path P(A->getValue());
- bool Exists;
- if (UsePCH) {
- P.appendSuffix("pch");
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- FoundPCH = true;
- else
- P.eraseSuffix();
- }
- if (!FoundPCH) {
- P.appendSuffix("pth");
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists)
- FoundPTH = true;
- else
- P.eraseSuffix();
- }
- if (!FoundPCH && !FoundPTH) {
- P.appendSuffix("gch");
- if (!llvm::sys::fs::exists(P.str(), Exists) && Exists) {
- FoundPCH = UsePCH;
- FoundPTH = !UsePCH;
- }
- else
- P.eraseSuffix();
- }
- if (FoundPCH || FoundPTH) {
- if (IsFirstImplicitInclude) {
- A->claim();
- if (UsePCH)
- CmdArgs.push_back("-include-pch");
- else
- CmdArgs.push_back("-include-pth");
- CmdArgs.push_back(Args.MakeArgString(P.str()));
- continue;
- } else {
- // Ignore the PCH if not first on command line and emit warning.
- D.Diag(diag::warn_drv_pch_not_first_include)
- << P.str() << A->getAsString(Args);
- }
- }
- }
- // Not translated, render as usual.
- A->claim();
- A->render(Args, CmdArgs);
- }
- Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
- Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
- options::OPT_index_header_map);
- // Add -Wp, and -Xassembler if using the preprocessor.
- // FIXME: There is a very unfortunate problem here, some troubled
- // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
- // really support that we would have to parse and then translate
- // those options. :(
- Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
- options::OPT_Xpreprocessor);
- // -I- is a deprecated GCC feature, reject it.
- if (Arg *A = Args.getLastArg(options::OPT_I_))
- D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
- // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
- // -isysroot to the CC1 invocation.
- StringRef sysroot = C.getSysRoot();
- if (sysroot != "") {
- if (!Args.hasArg(options::OPT_isysroot)) {
- CmdArgs.push_back("-isysroot");
- CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
- }
- }
-
- // If a module path was provided, pass it along. Otherwise, use a temporary
- // directory.
- if (Arg *A = Args.getLastArg(options::OPT_fmodule_cache_path)) {
- A->claim();
- A->render(Args, CmdArgs);
- } else {
- SmallString<128> DefaultModuleCache;
- llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
- DefaultModuleCache);
- llvm::sys::path::append(DefaultModuleCache, "clang-module-cache");
- CmdArgs.push_back("-fmodule-cache-path");
- CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
- }
-
- // Parse additional include paths from environment variables.
- // FIXME: We should probably sink the logic for handling these from the
- // frontend into the driver. It will allow deleting 4 otherwise unused flags.
- // CPATH - included following the user specified includes (but prior to
- // builtin and standard includes).
- addDirectoryList(Args, CmdArgs, "-I", "CPATH");
- // C_INCLUDE_PATH - system includes enabled when compiling C.
- addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
- // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
- addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
- // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
- addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
- // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
- addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
- // Add C++ include arguments, if needed.
- if (types::isCXX(Inputs[0].getType()))
- getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
- // Add system include arguments.
- getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
- }
- /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
- /// CPU.
- //
- // FIXME: This is redundant with -mcpu, why does LLVM use this.
- // FIXME: tblgen this, or kill it!
- static const char *getLLVMArchSuffixForARM(StringRef CPU) {
- return llvm::StringSwitch<const char *>(CPU)
- .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
- .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
- .Cases("arm920", "arm920t", "arm922t", "v4t")
- .Cases("arm940t", "ep9312","v4t")
- .Cases("arm10tdmi", "arm1020t", "v5")
- .Cases("arm9e", "arm926ej-s", "arm946e-s", "v5e")
- .Cases("arm966e-s", "arm968e-s", "arm10e", "v5e")
- .Cases("arm1020e", "arm1022e", "xscale", "iwmmxt", "v5e")
- .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "v6")
- .Cases("arm1176jzf-s", "mpcorenovfp", "mpcore", "v6")
- .Cases("arm1156t2-s", "arm1156t2f-s", "v6t2")
- .Cases("cortex-a5", "cortex-a8", "cortex-a9", "cortex-a15", "v7")
- .Case("cortex-r5", "v7r")
- .Case("cortex-m3", "v7m")
- .Case("cortex-m4", "v7m")
- .Case("cortex-m0", "v6m")
- .Case("cortex-a9-mp", "v7f")
- .Case("swift", "v7s")
- .Default("");
- }
- /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
- //
- // FIXME: tblgen this.
- static std::string getARMTargetCPU(const ArgList &Args,
- const llvm::Triple &Triple) {
- // FIXME: Warn on inconsistent use of -mcpu and -march.
- // If we have -mcpu=, use that.
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- StringRef MCPU = A->getValue();
- // Handle -mcpu=native.
- if (MCPU == "native")
- return llvm::sys::getHostCPUName();
- else
- return MCPU;
- }
- StringRef MArch;
- if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- // Otherwise, if we have -march= choose the base CPU for that arch.
- MArch = A->getValue();
- } else {
- // Otherwise, use the Arch from the triple.
- MArch = Triple.getArchName();
- }
- // Handle -march=native.
- std::string NativeMArch;
- if (MArch == "native") {
- std::string CPU = llvm::sys::getHostCPUName();
- if (CPU != "generic") {
- // Translate the native cpu into the architecture. The switch below will
- // then chose the minimum cpu for that arch.
- NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU);
- MArch = NativeMArch;
- }
- }
- return llvm::StringSwitch<const char *>(MArch)
- .Cases("armv2", "armv2a","arm2")
- .Case("armv3", "arm6")
- .Case("armv3m", "arm7m")
- .Cases("armv4", "armv4t", "arm7tdmi")
- .Cases("armv5", "armv5t", "arm10tdmi")
- .Cases("armv5e", "armv5te", "arm1022e")
- .Case("armv5tej", "arm926ej-s")
- .Cases("armv6", "armv6k", "arm1136jf-s")
- .Case("armv6j", "arm1136j-s")
- .Cases("armv6z", "armv6zk", "arm1176jzf-s")
- .Case("armv6t2", "arm1156t2-s")
- .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
- .Cases("armv7f", "armv7-f", "cortex-a9-mp")
- .Cases("armv7s", "armv7-s", "swift")
- .Cases("armv7r", "armv7-r", "cortex-r4")
- .Cases("armv7m", "armv7-m", "cortex-m3")
- .Case("ep9312", "ep9312")
- .Case("iwmmxt", "iwmmxt")
- .Case("xscale", "xscale")
- .Cases("armv6m", "armv6-m", "cortex-m0")
- // If all else failed, return the most base CPU LLVM supports.
- .Default("arm7tdmi");
- }
- // FIXME: Move to target hook.
- static bool isSignedCharDefault(const llvm::Triple &Triple) {
- switch (Triple.getArch()) {
- default:
- return true;
- case llvm::Triple::arm:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- if (Triple.isOSDarwin())
- return true;
- return false;
- }
- }
- // Handle -mfpu=.
- //
- // FIXME: Centralize feature selection, defaulting shouldn't be also in the
- // frontend target.
- static void addFPUArgs(const Driver &D, const Arg *A, const ArgList &Args,
- ArgStringList &CmdArgs) {
- StringRef FPU = A->getValue();
- // Set the target features based on the FPU.
- if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
- // Disable any default FPU support.
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-vfp2");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-vfp3");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neon");
- } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+vfp3");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+d16");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neon");
- } else if (FPU == "vfp") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+vfp2");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neon");
- } else if (FPU == "vfp3" || FPU == "vfpv3") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+vfp3");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neon");
- } else if (FPU == "neon") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+neon");
- } else
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
- }
- // Handle -mfpmath=.
- static void addFPMathArgs(const Driver &D, const Arg *A, const ArgList &Args,
- ArgStringList &CmdArgs, StringRef CPU) {
- StringRef FPMath = A->getValue();
-
- // Set the target features based on the FPMath.
- if (FPMath == "neon") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+neonfp");
-
- if (CPU != "cortex-a8" && CPU != "cortex-a9" && CPU != "cortex-a9-mp" &&
- CPU != "cortex-a15" && CPU != "cortex-a5")
- D.Diag(diag::err_drv_invalid_feature) << "-mfpmath=neon" << CPU;
-
- } else if (FPMath == "vfp" || FPMath == "vfp2" || FPMath == "vfp3" ||
- FPMath == "vfp4") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neonfp");
- // FIXME: Add warnings when disabling a feature not present for a given CPU.
- } else
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
- }
- // Select the float ABI as determined by -msoft-float, -mhard-float, and
- // -mfloat-abi=.
- static StringRef getARMFloatABI(const Driver &D,
- const ArgList &Args,
- const llvm::Triple &Triple) {
- StringRef FloatABI;
- if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
- options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- FloatABI = "soft";
- else if (A->getOption().matches(options::OPT_mhard_float))
- FloatABI = "hard";
- else {
- FloatABI = A->getValue();
- if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
- D.Diag(diag::err_drv_invalid_mfloat_abi)
- << A->getAsString(Args);
- FloatABI = "soft";
- }
- }
- }
- // If unspecified, choose the default based on the platform.
- if (FloatABI.empty()) {
- switch (Triple.getOS()) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS: {
- // Darwin defaults to "softfp" for v6 and v7.
- //
- // FIXME: Factor out an ARM class so we can cache the arch somewhere.
- std::string ArchName =
- getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
- if (StringRef(ArchName).startswith("v6") ||
- StringRef(ArchName).startswith("v7"))
- FloatABI = "softfp";
- else
- FloatABI = "soft";
- break;
- }
- case llvm::Triple::FreeBSD:
- // FreeBSD defaults to soft float
- FloatABI = "soft";
- break;
- default:
- switch(Triple.getEnvironment()) {
- case llvm::Triple::GNUEABIHF:
- FloatABI = "hard";
- break;
- case llvm::Triple::GNUEABI:
- FloatABI = "softfp";
- break;
- case llvm::Triple::EABI:
- // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
- FloatABI = "softfp";
- break;
- case llvm::Triple::Android: {
- std::string ArchName =
- getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
- if (StringRef(ArchName).startswith("v7"))
- FloatABI = "softfp";
- else
- FloatABI = "soft";
- break;
- }
- default:
- // Assume "soft", but warn the user we are guessing.
- FloatABI = "soft";
- D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
- break;
- }
- }
- }
- return FloatABI;
- }
- void Clang::AddARMTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs,
- bool KernelOrKext) const {
- const Driver &D = getToolChain().getDriver();
- // Get the effective triple, which takes into account the deployment target.
- std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
- llvm::Triple Triple(TripleStr);
- std::string CPUName = getARMTargetCPU(Args, Triple);
- // Select the ABI to use.
- //
- // FIXME: Support -meabi.
- const char *ABIName = 0;
- if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
- ABIName = A->getValue();
- } else if (Triple.isOSDarwin()) {
- // The backend is hardwired to assume AAPCS for M-class processors, ensure
- // the frontend matches that.
- if (StringRef(CPUName).startswith("cortex-m")) {
- ABIName = "aapcs";
- } else {
- ABIName = "apcs-gnu";
- }
- } else {
- // Select the default based on the platform.
- switch(Triple.getEnvironment()) {
- case llvm::Triple::Android:
- case llvm::Triple::GNUEABI:
- case llvm::Triple::GNUEABIHF:
- ABIName = "aapcs-linux";
- break;
- case llvm::Triple::EABI:
- ABIName = "aapcs";
- break;
- default:
- ABIName = "apcs-gnu";
- }
- }
- CmdArgs.push_back("-target-abi");
- CmdArgs.push_back(ABIName);
- // Set the CPU based on -march= and -mcpu=.
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(CPUName));
- // Determine floating point ABI from the options & target defaults.
- StringRef FloatABI = getARMFloatABI(D, Args, Triple);
- if (FloatABI == "soft") {
- // Floating point operations and argument passing are soft.
- //
- // FIXME: This changes CPP defines, we need -target-soft-float.
- CmdArgs.push_back("-msoft-float");
- CmdArgs.push_back("-mfloat-abi");
- CmdArgs.push_back("soft");
- } else if (FloatABI == "softfp") {
- // Floating point operations are hard, but argument passing is soft.
- CmdArgs.push_back("-mfloat-abi");
- CmdArgs.push_back("soft");
- } else {
- // Floating point operations and argument passing are hard.
- assert(FloatABI == "hard" && "Invalid float abi!");
- CmdArgs.push_back("-mfloat-abi");
- CmdArgs.push_back("hard");
- }
- // Set appropriate target features for floating point mode.
- //
- // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
- // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
- // stripped out by the ARM target.
- // Use software floating point operations?
- if (FloatABI == "soft") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+soft-float");
- }
- // Use software floating point argument passing?
- if (FloatABI != "hard") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+soft-float-abi");
- }
- // Honor -mfpu=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
- addFPUArgs(D, A, Args, CmdArgs);
- // Honor -mfpmath=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ))
- addFPMathArgs(D, A, Args, CmdArgs, getARMTargetCPU(Args, Triple));
- // Setting -msoft-float effectively disables NEON because of the GCC
- // implementation, although the same isn't true of VFP or VFP3.
- if (FloatABI == "soft") {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("-neon");
- }
- // Kernel code has more strict alignment requirements.
- if (KernelOrKext) {
- if (Triple.getOS() != llvm::Triple::IOS || Triple.isOSVersionLT(6)) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-long-calls");
- }
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-strict-align");
- // The kext linker doesn't know how to deal with movw/movt.
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-darwin-use-movt=0");
- }
- // Setting -mno-global-merge disables the codegen global merge pass. Setting
- // -mglobal-merge has no effect as the pass is enabled by default.
- if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
- options::OPT_mno_global_merge)) {
- if (A->getOption().matches(options::OPT_mno_global_merge))
- CmdArgs.push_back("-mno-global-merge");
- }
- if (Args.hasArg(options::OPT_mno_implicit_float))
- CmdArgs.push_back("-no-implicit-float");
- }
- // Translate MIPS CPU name alias option to CPU name.
- static StringRef getMipsCPUFromAlias(const Arg &A) {
- if (A.getOption().matches(options::OPT_mips32))
- return "mips32";
- if (A.getOption().matches(options::OPT_mips32r2))
- return "mips32r2";
- if (A.getOption().matches(options::OPT_mips64))
- return "mips64";
- if (A.getOption().matches(options::OPT_mips64r2))
- return "mips64r2";
- llvm_unreachable("Unexpected option");
- return "";
- }
- // Get CPU and ABI names. They are not independent
- // so we have to calculate them together.
- static void getMipsCPUAndABI(const ArgList &Args,
- const ToolChain &TC,
- StringRef &CPUName,
- StringRef &ABIName) {
- const char *DefMips32CPU = "mips32";
- const char *DefMips64CPU = "mips64";
- if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
- options::OPT_mcpu_EQ,
- options::OPT_mips_CPUs_Group)) {
- if (A->getOption().matches(options::OPT_mips_CPUs_Group))
- CPUName = getMipsCPUFromAlias(*A);
- else
- CPUName = A->getValue();
- }
- if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ))
- ABIName = A->getValue();
- // Setup default CPU and ABI names.
- if (CPUName.empty() && ABIName.empty()) {
- switch (TC.getTriple().getArch()) {
- default:
- llvm_unreachable("Unexpected triple arch name");
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- CPUName = DefMips32CPU;
- break;
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- CPUName = DefMips64CPU;
- break;
- }
- }
- if (!ABIName.empty()) {
- // Deduce CPU name from ABI name.
- CPUName = llvm::StringSwitch<const char *>(ABIName)
- .Cases("o32", "eabi", DefMips32CPU)
- .Cases("n32", "n64", DefMips64CPU)
- .Default("");
- }
- else if (!CPUName.empty()) {
- // Deduce ABI name from CPU name.
- ABIName = llvm::StringSwitch<const char *>(CPUName)
- .Cases("mips32", "mips32r2", "o32")
- .Cases("mips64", "mips64r2", "n64")
- .Default("");
- }
- // FIXME: Warn on inconsistent cpu and abi usage.
- }
- // Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
- // and -mfloat-abi=.
- static StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
- // Select the float ABI as determined by -msoft-float, -mhard-float,
- // and -mfloat-abi=.
- StringRef FloatABI;
- if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
- options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- FloatABI = "soft";
- else if (A->getOption().matches(options::OPT_mhard_float))
- FloatABI = "hard";
- else {
- FloatABI = A->getValue();
- if (FloatABI != "soft" && FloatABI != "single" && FloatABI != "hard") {
- D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
- FloatABI = "hard";
- }
- }
- }
- // If unspecified, choose the default based on the platform.
- if (FloatABI.empty()) {
- // Assume "hard", because it's a default value used by gcc.
- // When we start to recognize specific target MIPS processors,
- // we will be able to select the default more correctly.
- FloatABI = "hard";
- }
- return FloatABI;
- }
- static void AddTargetFeature(const ArgList &Args,
- ArgStringList &CmdArgs,
- OptSpecifier OnOpt,
- OptSpecifier OffOpt,
- StringRef FeatureName) {
- if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
- CmdArgs.push_back("-target-feature");
- if (A->getOption().matches(OnOpt))
- CmdArgs.push_back(Args.MakeArgString("+" + FeatureName));
- else
- CmdArgs.push_back(Args.MakeArgString("-" + FeatureName));
- }
- }
- void Clang::AddMIPSTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
- StringRef CPUName;
- StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(CPUName.data());
- CmdArgs.push_back("-target-abi");
- CmdArgs.push_back(ABIName.data());
- StringRef FloatABI = getMipsFloatABI(D, Args);
- if (FloatABI == "soft") {
- // Floating point operations and argument passing are soft.
- CmdArgs.push_back("-msoft-float");
- CmdArgs.push_back("-mfloat-abi");
- CmdArgs.push_back("soft");
- // FIXME: Note, this is a hack. We need to pass the selected float
- // mode to the MipsTargetInfoBase to define appropriate macros there.
- // Now it is the only method.
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+soft-float");
- }
- else if (FloatABI == "single") {
- // Restrict the use of hardware floating-point
- // instructions to 32-bit operations.
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+single-float");
- }
- else {
- // Floating point operations and argument passing are hard.
- assert(FloatABI == "hard" && "Invalid float abi!");
- CmdArgs.push_back("-mfloat-abi");
- CmdArgs.push_back("hard");
- }
- AddTargetFeature(Args, CmdArgs,
- options::OPT_mips16, options::OPT_mno_mips16,
- "mips16");
- AddTargetFeature(Args, CmdArgs,
- options::OPT_mdsp, options::OPT_mno_dsp,
- "dsp");
- AddTargetFeature(Args, CmdArgs,
- options::OPT_mdspr2, options::OPT_mno_dspr2,
- "dspr2");
- if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
- if (A->getOption().matches(options::OPT_mxgot)) {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-mxgot");
- }
- }
- if (Arg *A = Args.getLastArg(options::OPT_G)) {
- StringRef v = A->getValue();
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
- A->claim();
- }
- }
- /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
- static std::string getPPCTargetCPU(const ArgList &Args) {
- if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
- StringRef CPUName = A->getValue();
- if (CPUName == "native") {
- std::string CPU = llvm::sys::getHostCPUName();
- if (!CPU.empty() && CPU != "generic")
- return CPU;
- else
- return "";
- }
- return llvm::StringSwitch<const char *>(CPUName)
- .Case("common", "generic")
- .Case("440", "440")
- .Case("440fp", "440")
- .Case("450", "450")
- .Case("601", "601")
- .Case("602", "602")
- .Case("603", "603")
- .Case("603e", "603e")
- .Case("603ev", "603ev")
- .Case("604", "604")
- .Case("604e", "604e")
- .Case("620", "620")
- .Case("G3", "g3")
- .Case("7400", "7400")
- .Case("G4", "g4")
- .Case("7450", "7450")
- .Case("G4+", "g4+")
- .Case("750", "750")
- .Case("970", "970")
- .Case("G5", "g5")
- .Case("a2", "a2")
- .Case("e500mc", "e500mc")
- .Case("e5500", "e5500")
- .Case("power6", "pwr6")
- .Case("power7", "pwr7")
- .Case("powerpc", "ppc")
- .Case("powerpc64", "ppc64")
- .Default("");
- }
- return "";
- }
- void Clang::AddPPCTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- std::string TargetCPUName = getPPCTargetCPU(Args);
- // LLVM may default to generating code for the native CPU,
- // but, like gcc, we default to a more generic option for
- // each architecture. (except on Darwin)
- llvm::Triple Triple = getToolChain().getTriple();
- if (TargetCPUName.empty() && !Triple.isOSDarwin()) {
- if (Triple.getArch() == llvm::Triple::ppc64)
- TargetCPUName = "ppc64";
- else
- TargetCPUName = "ppc";
- }
- if (!TargetCPUName.empty()) {
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(TargetCPUName.c_str()));
- }
- }
- void Clang::AddSparcTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(A->getValue());
- }
- // Select the float ABI as determined by -msoft-float, -mhard-float, and
- StringRef FloatABI;
- if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
- options::OPT_mhard_float)) {
- if (A->getOption().matches(options::OPT_msoft_float))
- FloatABI = "soft";
- else if (A->getOption().matches(options::OPT_mhard_float))
- FloatABI = "hard";
- }
- // If unspecified, choose the default based on the platform.
- if (FloatABI.empty()) {
- switch (getToolChain().getTriple().getOS()) {
- default:
- // Assume "soft", but warn the user we are guessing.
- FloatABI = "soft";
- D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
- break;
- }
- }
- if (FloatABI == "soft") {
- // Floating point operations and argument passing are soft.
- //
- // FIXME: This changes CPP defines, we need -target-soft-float.
- CmdArgs.push_back("-msoft-float");
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back("+soft-float");
- } else {
- assert(FloatABI == "hard" && "Invalid float abi!");
- CmdArgs.push_back("-mhard-float");
- }
- }
- void Clang::AddX86TargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const bool isAndroid =
- getToolChain().getTriple().getEnvironment() == llvm::Triple::Android;
- if (!Args.hasFlag(options::OPT_mred_zone,
- options::OPT_mno_red_zone,
- true) ||
- Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext))
- CmdArgs.push_back("-disable-red-zone");
- if (Args.hasFlag(options::OPT_msoft_float,
- options::OPT_mno_soft_float,
- false))
- CmdArgs.push_back("-no-implicit-float");
- const char *CPUName = 0;
- if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
- if (StringRef(A->getValue()) == "native") {
- // FIXME: Reject attempts to use -march=native unless the target matches
- // the host.
- //
- // FIXME: We should also incorporate the detected target features for use
- // with -native.
- std::string CPU = llvm::sys::getHostCPUName();
- if (!CPU.empty() && CPU != "generic")
- CPUName = Args.MakeArgString(CPU);
- } else
- CPUName = A->getValue();
- }
- // Select the default CPU if none was given (or detection failed).
- if (!CPUName) {
- // FIXME: Need target hooks.
- if (getToolChain().getTriple().isOSDarwin()) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "core2";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "yonah";
- } else if (getToolChain().getOS().startswith("haiku")) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "i586";
- } else if (getToolChain().getOS().startswith("openbsd")) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "i486";
- } else if (getToolChain().getOS().startswith("bitrig")) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "i686";
- } else if (getToolChain().getOS().startswith("freebsd")) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "i486";
- } else if (getToolChain().getOS().startswith("netbsd")) {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- CPUName = "i486";
- } else {
- if (getToolChain().getArch() == llvm::Triple::x86_64)
- CPUName = "x86-64";
- else if (getToolChain().getArch() == llvm::Triple::x86)
- // All x86 devices running Android have core2 as their common
- // denominator. This makes a better choice than pentium4.
- CPUName = isAndroid ? "core2" : "pentium4";
- }
- }
- if (CPUName) {
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(CPUName);
- }
- // The required algorithm here is slightly strange: the options are applied
- // in order (so -mno-sse -msse2 disables SSE3), but any option that gets
- // directly overridden later is ignored (so "-mno-sse -msse2 -mno-sse2 -msse"
- // is equivalent to "-mno-sse2 -msse"). The -cc1 handling deals with the
- // former correctly, but not the latter; handle directly-overridden
- // attributes here.
- llvm::StringMap<unsigned> PrevFeature;
- std::vector<const char*> Features;
- for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
- ie = Args.filtered_end(); it != ie; ++it) {
- StringRef Name = (*it)->getOption().getName();
- (*it)->claim();
- // Skip over "-m".
- assert(Name.startswith("m") && "Invalid feature name.");
- Name = Name.substr(1);
- bool IsNegative = Name.startswith("no-");
- if (IsNegative)
- Name = Name.substr(3);
- unsigned& Prev = PrevFeature[Name];
- if (Prev)
- Features[Prev - 1] = 0;
- Prev = Features.size() + 1;
- Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
- }
- for (unsigned i = 0; i < Features.size(); i++) {
- if (Features[i]) {
- CmdArgs.push_back("-target-feature");
- CmdArgs.push_back(Features[i]);
- }
- }
- }
- static inline bool HasPICArg(const ArgList &Args) {
- return Args.hasArg(options::OPT_fPIC)
- || Args.hasArg(options::OPT_fpic);
- }
- static Arg *GetLastSmallDataThresholdArg(const ArgList &Args) {
- return Args.getLastArg(options::OPT_G,
- options::OPT_G_EQ,
- options::OPT_msmall_data_threshold_EQ);
- }
- static std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) {
- std::string value;
- if (HasPICArg(Args))
- value = "0";
- else if (Arg *A = GetLastSmallDataThresholdArg(Args)) {
- value = A->getValue();
- A->claim();
- }
- return value;
- }
- void Clang::AddHexagonTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- llvm::Triple Triple = getToolChain().getTriple();
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(
- "hexagon"
- + toolchains::Hexagon_TC::GetTargetCPU(Args)));
- CmdArgs.push_back("-fno-signed-char");
- CmdArgs.push_back("-mqdsp6-compat");
- CmdArgs.push_back("-Wreturn-type");
- std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
- if (!SmallDataThreshold.empty()) {
- CmdArgs.push_back ("-mllvm");
- CmdArgs.push_back(Args.MakeArgString(
- "-hexagon-small-data-threshold=" + SmallDataThreshold));
- }
- if (!Args.hasArg(options::OPT_fno_short_enums))
- CmdArgs.push_back("-fshort-enums");
- if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
- CmdArgs.push_back ("-mllvm");
- CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near");
- }
- CmdArgs.push_back ("-mllvm");
- CmdArgs.push_back ("-machine-sink-split=0");
- }
- static bool
- shouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
- const llvm::Triple &Triple) {
- // We use the zero-cost exception tables for Objective-C if the non-fragile
- // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
- // later.
- if (runtime.isNonFragile())
- return true;
- if (!Triple.isOSDarwin())
- return false;
- return (!Triple.isMacOSXVersionLT(10,5) &&
- (Triple.getArch() == llvm::Triple::x86_64 ||
- Triple.getArch() == llvm::Triple::arm));
- }
- /// addExceptionArgs - Adds exception related arguments to the driver command
- /// arguments. There's a master flag, -fexceptions and also language specific
- /// flags to enable/disable C++ and Objective-C exceptions.
- /// This makes it possible to for example disable C++ exceptions but enable
- /// Objective-C exceptions.
- static void addExceptionArgs(const ArgList &Args, types::ID InputType,
- const llvm::Triple &Triple,
- bool KernelOrKext,
- const ObjCRuntime &objcRuntime,
- ArgStringList &CmdArgs) {
- if (KernelOrKext) {
- // -mkernel and -fapple-kext imply no exceptions, so claim exception related
- // arguments now to avoid warnings about unused arguments.
- Args.ClaimAllArgs(options::OPT_fexceptions);
- Args.ClaimAllArgs(options::OPT_fno_exceptions);
- Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
- Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
- Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
- Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
- return;
- }
- // Exceptions are enabled by default.
- bool ExceptionsEnabled = true;
- // This keeps track of whether exceptions were explicitly turned on or off.
- bool DidHaveExplicitExceptionFlag = false;
- if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
- options::OPT_fno_exceptions)) {
- if (A->getOption().matches(options::OPT_fexceptions))
- ExceptionsEnabled = true;
- else
- ExceptionsEnabled = false;
- DidHaveExplicitExceptionFlag = true;
- }
- bool ShouldUseExceptionTables = false;
- // Exception tables and cleanups can be enabled with -fexceptions even if the
- // language itself doesn't support exceptions.
- if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
- ShouldUseExceptionTables = true;
- // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
- // is not necessarily sensible, but follows GCC.
- if (types::isObjC(InputType) &&
- Args.hasFlag(options::OPT_fobjc_exceptions,
- options::OPT_fno_objc_exceptions,
- true)) {
- CmdArgs.push_back("-fobjc-exceptions");
- ShouldUseExceptionTables |=
- shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
- }
- if (types::isCXX(InputType)) {
- bool CXXExceptionsEnabled = ExceptionsEnabled;
- if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
- options::OPT_fno_cxx_exceptions,
- options::OPT_fexceptions,
- options::OPT_fno_exceptions)) {
- if (A->getOption().matches(options::OPT_fcxx_exceptions))
- CXXExceptionsEnabled = true;
- else if (A->getOption().matches(options::OPT_fno_cxx_exceptions))
- CXXExceptionsEnabled = false;
- }
- if (CXXExceptionsEnabled) {
- CmdArgs.push_back("-fcxx-exceptions");
- ShouldUseExceptionTables = true;
- }
- }
- if (ShouldUseExceptionTables)
- CmdArgs.push_back("-fexceptions");
- }
- static bool ShouldDisableCFI(const ArgList &Args,
- const ToolChain &TC) {
- bool Default = true;
- if (TC.getTriple().isOSDarwin()) {
- // The native darwin assembler doesn't support cfi directives, so
- // we disable them if we think the .s file will be passed to it.
- Default = Args.hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- TC.IsIntegratedAssemblerDefault());
- }
- return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
- options::OPT_fno_dwarf2_cfi_asm,
- Default);
- }
- static bool ShouldDisableDwarfDirectory(const ArgList &Args,
- const ToolChain &TC) {
- bool IsIADefault = TC.IsIntegratedAssemblerDefault();
- bool UseIntegratedAs = Args.hasFlag(options::OPT_integrated_as,
- options::OPT_no_integrated_as,
- IsIADefault);
- bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
- options::OPT_fno_dwarf_directory_asm,
- UseIntegratedAs);
- return !UseDwarfDirectory;
- }
- /// \brief Check whether the given input tree contains any compilation actions.
- static bool ContainsCompileAction(const Action *A) {
- if (isa<CompileJobAction>(A))
- return true;
- for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
- if (ContainsCompileAction(*it))
- return true;
- return false;
- }
- /// \brief Check if -relax-all should be passed to the internal assembler.
- /// This is done by default when compiling non-assembler source with -O0.
- static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
- bool RelaxDefault = true;
- if (Arg *A = Args.getLastArg(options::OPT_O_Group))
- RelaxDefault = A->getOption().matches(options::OPT_O0);
- if (RelaxDefault) {
- RelaxDefault = false;
- for (ActionList::const_iterator it = C.getActions().begin(),
- ie = C.getActions().end(); it != ie; ++it) {
- if (ContainsCompileAction(*it)) {
- RelaxDefault = true;
- break;
- }
- }
- }
- return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
- RelaxDefault);
- }
- SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) {
- Kind = 0;
- for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
- unsigned Add, Remove;
- if (!parse(D, Args, *I, Add, Remove, true))
- continue;
- (*I)->claim();
- Kind |= Add;
- Kind &= ~Remove;
- }
- // Only one runtime library can be used at once.
- bool NeedsAsan = needsAsanRt();
- bool NeedsTsan = needsTsanRt();
- bool NeedsMsan = needsMsanRt();
- if (NeedsAsan && NeedsTsan)
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << lastArgumentForKind(D, Args, NeedsAsanRt)
- << lastArgumentForKind(D, Args, NeedsTsanRt);
- if (NeedsAsan && NeedsMsan)
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << lastArgumentForKind(D, Args, NeedsAsanRt)
- << lastArgumentForKind(D, Args, NeedsMsanRt);
- if (NeedsTsan && NeedsMsan)
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << lastArgumentForKind(D, Args, NeedsTsanRt)
- << lastArgumentForKind(D, Args, NeedsMsanRt);
- // If -fsanitize contains extra features of ASan, it should also
- // explicitly contain -fsanitize=address.
- if (NeedsAsan && ((Kind & Address) == 0))
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << lastArgumentForKind(D, Args, NeedsAsanRt)
- << "-fsanitize=address";
- // Parse -f(no-)sanitize-blacklist options.
- if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
- options::OPT_fno_sanitize_blacklist)) {
- if (BLArg->getOption().matches(options::OPT_fsanitize_blacklist)) {
- std::string BLPath = BLArg->getValue();
- bool BLExists = false;
- if (!llvm::sys::fs::exists(BLPath, BLExists) && BLExists)
- BlacklistFile = BLPath;
- else
- D.Diag(diag::err_drv_no_such_file) << BLPath;
- }
- }
- // Parse -f(no-)sanitize-memory-track-origins options.
- if (Kind & Memory)
- MsanTrackOrigins =
- Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
- options::OPT_fno_sanitize_memory_track_origins,
- /* Default */false);
- }
- /// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
- /// This needs to be called before we add the C run-time (malloc, etc).
- static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if(TC.getTriple().getEnvironment() == llvm::Triple::Android) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_asan_android_requires_pie);
- }
- SmallString<128> LibAsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibAsan, "lib", "linux",
- (Twine("libclang_rt.asan-") +
- TC.getArchName() + "-android.so"));
- CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
- } else {
- if (!Args.hasArg(options::OPT_shared)) {
- // LibAsan is "libclang_rt.asan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibAsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibAsan, "lib", "linux",
- (Twine("libclang_rt.asan-") +
- TC.getArchName() + ".a"));
- // The ASan runtime needs to come before -lstdc++ (or -lc++, libstdc++.a,
- // etc.) so that the linker picks ASan's versions of the global 'operator
- // new' and 'operator delete' symbols. We take the extreme (but simple)
- // strategy of inserting it at the front of the link command. It also
- // needs to be forced to end up in the executable, so wrap it in
- // whole-archive.
- SmallVector<const char*, 3> PrefixArgs;
- PrefixArgs.push_back("-whole-archive");
- PrefixArgs.push_back(Args.MakeArgString(LibAsan));
- PrefixArgs.push_back("-no-whole-archive");
- CmdArgs.insert(CmdArgs.begin(), PrefixArgs.begin(), PrefixArgs.end());
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
- }
- }
- }
- /// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
- /// This needs to be called before we add the C run-time (malloc, etc).
- static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
- "-fsanitize=thread" << "-pie";
- // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibTsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibTsan, "lib", "linux",
- (Twine("libclang_rt.tsan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibTsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
- }
- }
- /// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
- /// This needs to be called before we add the C run-time (malloc, etc).
- static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (!Args.hasArg(options::OPT_pie))
- TC.getDriver().Diag(diag::err_drv_argument_only_allowed_with) <<
- "-fsanitize=memory" << "-pie";
- // LibMsan is "libclang_rt.msan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibMsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibMsan, "lib", "linux",
- (Twine("libclang_rt.msan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibMsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-ldl");
- CmdArgs.push_back("-export-dynamic");
- }
- }
- /// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
- /// (Linux).
- static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- if (!Args.hasArg(options::OPT_shared)) {
- // LibUbsan is "libclang_rt.ubsan-<ArchName>.a" in the Linux library
- // resource directory.
- SmallString<128> LibUbsan(TC.getDriver().ResourceDir);
- llvm::sys::path::append(LibUbsan, "lib", "linux",
- (Twine("libclang_rt.ubsan-") +
- TC.getArchName() + ".a"));
- CmdArgs.push_back(Args.MakeArgString(LibUbsan));
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-export-dynamic");
- }
- }
- static bool shouldUseFramePointer(const ArgList &Args,
- const llvm::Triple &Triple) {
- if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
- options::OPT_fomit_frame_pointer))
- return A->getOption().matches(options::OPT_fno_omit_frame_pointer);
- // Don't use a frame pointer on linux x86 and x86_64 if optimizing.
- if ((Triple.getArch() == llvm::Triple::x86_64 ||
- Triple.getArch() == llvm::Triple::x86) &&
- Triple.getOS() == llvm::Triple::Linux) {
- if (Arg *A = Args.getLastArg(options::OPT_O_Group))
- if (!A->getOption().matches(options::OPT_O0))
- return false;
- }
- return true;
- }
- /// If the PWD environment variable is set, add a CC1 option to specify the
- /// debug compilation directory.
- static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
- if (const char *pwd = ::getenv("PWD")) {
- // GCC also verifies that stat(pwd) and stat(".") have the same inode
- // number. Not doing those because stats are slow, but we could.
- if (llvm::sys::path::is_absolute(pwd)) {
- std::string CompDir = pwd;
- CmdArgs.push_back("-fdebug-compilation-dir");
- CmdArgs.push_back(Args.MakeArgString(CompDir));
- }
- }
- }
- void Clang::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
- options::OPT_fapple_kext);
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
- // Invoke ourselves in -cc1 mode.
- //
- // FIXME: Implement custom jobs for internal actions.
- CmdArgs.push_back("-cc1");
- // Add the "effective" target triple.
- CmdArgs.push_back("-triple");
- std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
- CmdArgs.push_back(Args.MakeArgString(TripleStr));
- // Select the appropriate action.
- RewriteKind rewriteKind = RK_None;
-
- if (isa<AnalyzeJobAction>(JA)) {
- assert(JA.getType() == types::TY_Plist && "Invalid output type.");
- CmdArgs.push_back("-analyze");
- } else if (isa<MigrateJobAction>(JA)) {
- CmdArgs.push_back("-migrate");
- } else if (isa<PreprocessJobAction>(JA)) {
- if (Output.getType() == types::TY_Dependencies)
- CmdArgs.push_back("-Eonly");
- else
- CmdArgs.push_back("-E");
- } else if (isa<AssembleJobAction>(JA)) {
- CmdArgs.push_back("-emit-obj");
- if (UseRelaxAll(C, Args))
- CmdArgs.push_back("-mrelax-all");
- // When using an integrated assembler, translate -Wa, and -Xassembler
- // options.
- for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA,
- options::OPT_Xassembler),
- ie = Args.filtered_end(); it != ie; ++it) {
- const Arg *A = *it;
- A->claim();
- for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
- StringRef Value = A->getValue(i);
- if (Value == "-force_cpusubtype_ALL") {
- // Do nothing, this is the default and we don't support anything else.
- } else if (Value == "-L") {
- CmdArgs.push_back("-msave-temp-labels");
- } else if (Value == "--fatal-warnings") {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-fatal-assembler-warnings");
- } else if (Value == "--noexecstack") {
- CmdArgs.push_back("-mnoexecstack");
- } else {
- D.Diag(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << Value;
- }
- }
- }
- // Also ignore explicit -force_cpusubtype_ALL option.
- (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
- } else if (isa<PrecompileJobAction>(JA)) {
- // Use PCH if the user requested it.
- bool UsePCH = D.CCCUsePCH;
- if (JA.getType() == types::TY_Nothing)
- CmdArgs.push_back("-fsyntax-only");
- else if (UsePCH)
- CmdArgs.push_back("-emit-pch");
- else
- CmdArgs.push_back("-emit-pth");
- } else {
- assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
- if (JA.getType() == types::TY_Nothing) {
- CmdArgs.push_back("-fsyntax-only");
- } else if (JA.getType() == types::TY_LLVM_IR ||
- JA.getType() == types::TY_LTO_IR) {
- CmdArgs.push_back("-emit-llvm");
- } else if (JA.getType() == types::TY_LLVM_BC ||
- JA.getType() == types::TY_LTO_BC) {
- CmdArgs.push_back("-emit-llvm-bc");
- } else if (JA.getType() == types::TY_PP_Asm) {
- CmdArgs.push_back("-S");
- } else if (JA.getType() == types::TY_AST) {
- CmdArgs.push_back("-emit-pch");
- } else if (JA.getType() == types::TY_RewrittenObjC) {
- CmdArgs.push_back("-rewrite-objc");
- rewriteKind = RK_NonFragile;
- } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
- CmdArgs.push_back("-rewrite-objc");
- rewriteKind = RK_Fragile;
- } else {
- assert(JA.getType() == types::TY_PP_Asm &&
- "Unexpected output type!");
- }
- }
- // The make clang go fast button.
- CmdArgs.push_back("-disable-free");
- // Disable the verification pass in -asserts builds.
- #ifdef NDEBUG
- CmdArgs.push_back("-disable-llvm-verifier");
- #endif
- // Set the main file name, so that debug info works even with
- // -save-temps.
- CmdArgs.push_back("-main-file-name");
- CmdArgs.push_back(getBaseInputName(Args, Inputs));
- // Some flags which affect the language (via preprocessor
- // defines).
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("-static-define");
- if (isa<AnalyzeJobAction>(JA)) {
- // Enable region store model by default.
- CmdArgs.push_back("-analyzer-store=region");
- // Treat blocks as analysis entry points.
- CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
- CmdArgs.push_back("-analyzer-eagerly-assume");
- // Add default argument set.
- if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
- CmdArgs.push_back("-analyzer-checker=core");
- if (getToolChain().getTriple().getOS() != llvm::Triple::Win32)
- CmdArgs.push_back("-analyzer-checker=unix");
- if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
- CmdArgs.push_back("-analyzer-checker=osx");
-
- CmdArgs.push_back("-analyzer-checker=deadcode");
-
- // Enable the following experimental checkers for testing.
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
- CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
- }
- // Set the output format. The default is plist, for (lame) historical
- // reasons.
- CmdArgs.push_back("-analyzer-output");
- if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
- CmdArgs.push_back(A->getValue());
- else
- CmdArgs.push_back("plist");
- // Disable the presentation of standard compiler warnings when
- // using --analyze. We only want to show static analyzer diagnostics
- // or frontend errors.
- CmdArgs.push_back("-w");
- // Add -Xanalyzer arguments when running as analyzer.
- Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
- }
- CheckCodeGenerationOptions(D, Args);
- // For the PIC and PIE flag options, this logic is different from the legacy
- // logic in very old versions of GCC, as that logic was just a bug no one had
- // ever fixed. This logic is both more rational and consistent with GCC's new
- // logic now that the bugs are fixed. The last argument relating to either
- // PIC or PIE wins, and no other argument is used. If the last argument is
- // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any
- // PIE option implicitly enables PIC at the same level.
- bool PIE = false;
- bool PIC = getToolChain().isPICDefault();
- bool IsPICLevelTwo = PIC;
- if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
- options::OPT_fpic, options::OPT_fno_pic,
- options::OPT_fPIE, options::OPT_fno_PIE,
- options::OPT_fpie, options::OPT_fno_pie)) {
- Option O = A->getOption();
- if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
- O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
- PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
- PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
- IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
- O.matches(options::OPT_fPIC);
- } else {
- PIE = PIC = false;
- }
- }
- // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
- // is forced, then neither PIC nor PIE flags will have no effect.
- if (getToolChain().isPICDefaultForced()) {
- PIE = false;
- PIC = getToolChain().isPICDefault();
- IsPICLevelTwo = PIC;
- }
- // Inroduce a Darwin-specific hack. If the default is PIC but the flags
- // specified while enabling PIC enabled level 1 PIC, just force it back to
- // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
- // informal testing).
- if (PIC && getToolChain().getTriple().isOSDarwin())
- IsPICLevelTwo |= getToolChain().isPICDefault();
- // Note that these flags are trump-cards. Regardless of the order w.r.t. the
- // PIC or PIE options above, if these show up, PIC is disabled.
- llvm::Triple Triple(TripleStr);
- if ((Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) &&
- (Triple.getOS() != llvm::Triple::IOS ||
- Triple.isOSVersionLT(6)))
- PIC = PIE = false;
- if (Args.hasArg(options::OPT_static))
- PIC = PIE = false;
- if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
- // This is a very special mode. It trumps the other modes, almost no one
- // uses it, and it isn't even valid on any OS but Darwin.
- if (!getToolChain().getTriple().isOSDarwin())
- D.Diag(diag::err_drv_unsupported_opt_for_target)
- << A->getSpelling() << getToolChain().getTriple().str();
- // FIXME: Warn when this flag trumps some other PIC or PIE flag.
- CmdArgs.push_back("-mrelocation-model");
- CmdArgs.push_back("dynamic-no-pic");
- // Only a forced PIC mode can cause the actual compile to have PIC defines
- // etc., no flags are sufficient. This behavior was selected to closely
- // match that of llvm-gcc and Apple GCC before that.
- if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
- CmdArgs.push_back("-pic-level");
- CmdArgs.push_back("2");
- }
- } else {
- // Currently, LLVM only knows about PIC vs. static; the PIE differences are
- // handled in Clang's IRGen by the -pie-level flag.
- CmdArgs.push_back("-mrelocation-model");
- CmdArgs.push_back(PIC ? "pic" : "static");
- if (PIC) {
- CmdArgs.push_back("-pic-level");
- CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
- if (PIE) {
- CmdArgs.push_back("-pie-level");
- CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
- }
- }
- }
- if (!Args.hasFlag(options::OPT_fmerge_all_constants,
- options::OPT_fno_merge_all_constants))
- CmdArgs.push_back("-fno-merge-all-constants");
- // LLVM Code Generator Options.
- if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
- CmdArgs.push_back("-mregparm");
- CmdArgs.push_back(A->getValue());
- }
- if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
- CmdArgs.push_back("-mrtd");
- if (shouldUseFramePointer(Args, getToolChain().getTriple()))
- CmdArgs.push_back("-mdisable-fp-elim");
- if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
- options::OPT_fno_zero_initialized_in_bss))
- CmdArgs.push_back("-mno-zero-initialized-in-bss");
- if (!Args.hasFlag(options::OPT_fstrict_aliasing,
- options::OPT_fno_strict_aliasing,
- getToolChain().IsStrictAliasingDefault()))
- CmdArgs.push_back("-relaxed-aliasing");
- if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
- false))
- CmdArgs.push_back("-fstrict-enums");
- if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
- options::OPT_fno_optimize_sibling_calls))
- CmdArgs.push_back("-mdisable-tail-calls");
- // Handle various floating point optimization flags, mapping them to the
- // appropriate LLVM code generation flags. The pattern for all of these is to
- // default off the codegen optimizations, and if any flag enables them and no
- // flag disables them after the flag enabling them, enable the codegen
- // optimization. This is complicated by several "umbrella" flags.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_ffinite_math_only,
- options::OPT_fno_finite_math_only,
- options::OPT_fhonor_infinities,
- options::OPT_fno_honor_infinities))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_finite_math_only &&
- A->getOption().getID() != options::OPT_fhonor_infinities)
- CmdArgs.push_back("-menable-no-infs");
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_ffinite_math_only,
- options::OPT_fno_finite_math_only,
- options::OPT_fhonor_nans,
- options::OPT_fno_honor_nans))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_finite_math_only &&
- A->getOption().getID() != options::OPT_fhonor_nans)
- CmdArgs.push_back("-menable-no-nans");
- // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
- bool MathErrno = getToolChain().IsMathErrnoDefault();
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_fmath_errno,
- options::OPT_fno_math_errno))
- MathErrno = A->getOption().getID() == options::OPT_fmath_errno;
- if (MathErrno)
- CmdArgs.push_back("-fmath-errno");
- // There are several flags which require disabling very specific
- // optimizations. Any of these being disabled forces us to turn off the
- // entire set of LLVM optimizations, so collect them through all the flag
- // madness.
- bool AssociativeMath = false;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_funsafe_math_optimizations,
- options::OPT_fno_unsafe_math_optimizations,
- options::OPT_fassociative_math,
- options::OPT_fno_associative_math))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
- A->getOption().getID() != options::OPT_fno_associative_math)
- AssociativeMath = true;
- bool ReciprocalMath = false;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_funsafe_math_optimizations,
- options::OPT_fno_unsafe_math_optimizations,
- options::OPT_freciprocal_math,
- options::OPT_fno_reciprocal_math))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
- A->getOption().getID() != options::OPT_fno_reciprocal_math)
- ReciprocalMath = true;
- bool SignedZeros = true;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_funsafe_math_optimizations,
- options::OPT_fno_unsafe_math_optimizations,
- options::OPT_fsigned_zeros,
- options::OPT_fno_signed_zeros))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
- A->getOption().getID() != options::OPT_fsigned_zeros)
- SignedZeros = false;
- bool TrappingMath = true;
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_funsafe_math_optimizations,
- options::OPT_fno_unsafe_math_optimizations,
- options::OPT_ftrapping_math,
- options::OPT_fno_trapping_math))
- if (A->getOption().getID() != options::OPT_fno_fast_math &&
- A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
- A->getOption().getID() != options::OPT_ftrapping_math)
- TrappingMath = false;
- if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
- !TrappingMath)
- CmdArgs.push_back("-menable-unsafe-fp-math");
- // Validate and pass through -fp-contract option.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
- options::OPT_fno_fast_math,
- options::OPT_ffp_contract)) {
- if (A->getOption().getID() == options::OPT_ffp_contract) {
- StringRef Val = A->getValue();
- if (Val == "fast" || Val == "on" || Val == "off") {
- CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
- } else {
- D.Diag(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << Val;
- }
- } else if (A->getOption().getID() == options::OPT_ffast_math) {
- // If fast-math is set then set the fp-contract mode to fast.
- CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
- }
- }
- // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
- // and if we find them, tell the frontend to provide the appropriate
- // preprocessor macros. This is distinct from enabling any optimizations as
- // these options induce language changes which must survive serialization
- // and deserialization, etc.
- if (Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math))
- if (A->getOption().matches(options::OPT_ffast_math))
- CmdArgs.push_back("-ffast-math");
- if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math))
- if (A->getOption().matches(options::OPT_ffinite_math_only))
- CmdArgs.push_back("-ffinite-math-only");
- // Decide whether to use verbose asm. Verbose assembly is the default on
- // toolchains which have the integrated assembler on by default.
- bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
- if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
- IsVerboseAsmDefault) ||
- Args.hasArg(options::OPT_dA))
- CmdArgs.push_back("-masm-verbose");
- if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
- CmdArgs.push_back("-mdebug-pass");
- CmdArgs.push_back("Structure");
- }
- if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
- CmdArgs.push_back("-mdebug-pass");
- CmdArgs.push_back("Arguments");
- }
- // Enable -mconstructor-aliases except on darwin, where we have to
- // work around a linker bug; see <rdar://problem/7651567>.
- if (!getToolChain().getTriple().isOSDarwin())
- CmdArgs.push_back("-mconstructor-aliases");
- // Darwin's kernel doesn't support guard variables; just die if we
- // try to use them.
- if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
- CmdArgs.push_back("-fforbid-guard-variables");
- if (Args.hasArg(options::OPT_mms_bitfields)) {
- CmdArgs.push_back("-mms-bitfields");
- }
- // This is a coarse approximation of what llvm-gcc actually does, both
- // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
- // complicated ways.
- bool AsynchronousUnwindTables =
- Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
- options::OPT_fno_asynchronous_unwind_tables,
- getToolChain().IsUnwindTablesDefault() &&
- !KernelOrKext);
- if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
- AsynchronousUnwindTables))
- CmdArgs.push_back("-munwind-tables");
- getToolChain().addClangTargetOptions(Args, CmdArgs);
- if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
- CmdArgs.push_back("-mlimit-float-precision");
- CmdArgs.push_back(A->getValue());
- }
- // FIXME: Handle -mtune=.
- (void) Args.hasArg(options::OPT_mtune_EQ);
- if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
- CmdArgs.push_back("-mcode-model");
- CmdArgs.push_back(A->getValue());
- }
- // Add target specific cpu and features flags.
- switch(getToolChain().getTriple().getArch()) {
- default:
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
- break;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- AddMIPSTargetArgs(Args, CmdArgs);
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- AddPPCTargetArgs(Args, CmdArgs);
- break;
- case llvm::Triple::sparc:
- AddSparcTargetArgs(Args, CmdArgs);
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- AddX86TargetArgs(Args, CmdArgs);
- break;
- case llvm::Triple::hexagon:
- AddHexagonTargetArgs(Args, CmdArgs);
- break;
- }
- // Pass the linker version in use.
- if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
- CmdArgs.push_back("-target-linker-version");
- CmdArgs.push_back(A->getValue());
- }
- // -mno-omit-leaf-frame-pointer is the default on Darwin.
- if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
- options::OPT_mno_omit_leaf_frame_pointer,
- !getToolChain().getTriple().isOSDarwin()))
- CmdArgs.push_back("-momit-leaf-frame-pointer");
- // Explicitly error on some things we know we don't support and can't just
- // ignore.
- types::ID InputType = Inputs[0].getType();
- if (!Args.hasArg(options::OPT_fallow_unsupported)) {
- Arg *Unsupported;
- if (types::isCXX(InputType) &&
- getToolChain().getTriple().isOSDarwin() &&
- getToolChain().getTriple().getArch() == llvm::Triple::x86) {
- if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
- (Unsupported = Args.getLastArg(options::OPT_mkernel)))
- D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
- << Unsupported->getOption().getName();
- }
- }
- Args.AddAllArgs(CmdArgs, options::OPT_v);
- Args.AddLastArg(CmdArgs, options::OPT_H);
- if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
- CmdArgs.push_back("-header-include-file");
- CmdArgs.push_back(D.CCPrintHeadersFilename ?
- D.CCPrintHeadersFilename : "-");
- }
- Args.AddLastArg(CmdArgs, options::OPT_P);
- Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
- if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
- CmdArgs.push_back("-diagnostic-log-file");
- CmdArgs.push_back(D.CCLogDiagnosticsFilename ?
- D.CCLogDiagnosticsFilename : "-");
- }
- // Use the last option from "-g" group. "-gline-tables-only" is
- // preserved, all other debug options are substituted with "-g".
- Args.ClaimAllArgs(options::OPT_g_Group);
- if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
- if (A->getOption().matches(options::OPT_gline_tables_only)) {
- CmdArgs.push_back("-gline-tables-only");
- } else if (!A->getOption().matches(options::OPT_g0) &&
- !A->getOption().matches(options::OPT_ggdb0)) {
- CmdArgs.push_back("-g");
- }
- }
- // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
- Args.ClaimAllArgs(options::OPT_g_flags_Group);
- if (Args.hasArg(options::OPT_gcolumn_info))
- CmdArgs.push_back("-dwarf-column-info");
- Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
- Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
- Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
- if (Args.hasArg(options::OPT_ftest_coverage) ||
- Args.hasArg(options::OPT_coverage))
- CmdArgs.push_back("-femit-coverage-notes");
- if (Args.hasArg(options::OPT_fprofile_arcs) ||
- Args.hasArg(options::OPT_coverage))
- CmdArgs.push_back("-femit-coverage-data");
- if (C.getArgs().hasArg(options::OPT_c) ||
- C.getArgs().hasArg(options::OPT_S)) {
- if (Output.isFilename()) {
- CmdArgs.push_back("-coverage-file");
- SmallString<128> absFilename(Output.getFilename());
- llvm::sys::fs::make_absolute(absFilename);
- CmdArgs.push_back(Args.MakeArgString(absFilename));
- }
- }
- // Pass options for controlling the default header search paths.
- if (Args.hasArg(options::OPT_nostdinc)) {
- CmdArgs.push_back("-nostdsysteminc");
- CmdArgs.push_back("-nobuiltininc");
- } else {
- if (Args.hasArg(options::OPT_nostdlibinc))
- CmdArgs.push_back("-nostdsysteminc");
- Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
- Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
- }
- // Pass the path to compiler resource files.
- CmdArgs.push_back("-resource-dir");
- CmdArgs.push_back(D.ResourceDir.c_str());
- Args.AddLastArg(CmdArgs, options::OPT_working_directory);
- bool ARCMTEnabled = false;
- if (!Args.hasArg(options::OPT_fno_objc_arc)) {
- if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
- options::OPT_ccc_arcmt_modify,
- options::OPT_ccc_arcmt_migrate)) {
- ARCMTEnabled = true;
- switch (A->getOption().getID()) {
- default:
- llvm_unreachable("missed a case");
- case options::OPT_ccc_arcmt_check:
- CmdArgs.push_back("-arcmt-check");
- break;
- case options::OPT_ccc_arcmt_modify:
- CmdArgs.push_back("-arcmt-modify");
- break;
- case options::OPT_ccc_arcmt_migrate:
- CmdArgs.push_back("-arcmt-migrate");
- CmdArgs.push_back("-mt-migrate-directory");
- CmdArgs.push_back(A->getValue());
- Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
- Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
- break;
- }
- }
- }
- if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
- if (ARCMTEnabled) {
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << A->getAsString(Args) << "-ccc-arcmt-migrate";
- }
- CmdArgs.push_back("-mt-migrate-directory");
- CmdArgs.push_back(A->getValue());
- if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
- options::OPT_objcmt_migrate_subscripting)) {
- // None specified, means enable them all.
- CmdArgs.push_back("-objcmt-migrate-literals");
- CmdArgs.push_back("-objcmt-migrate-subscripting");
- } else {
- Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
- Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
- }
- }
- // Add preprocessing options like -I, -D, etc. if we are using the
- // preprocessor.
- //
- // FIXME: Support -fpreprocessed
- if (types::getPreprocessedType(InputType) != types::TY_INVALID)
- AddPreprocessingOptions(C, D, Args, CmdArgs, Output, Inputs);
- // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
- // that "The compiler can only warn and ignore the option if not recognized".
- // When building with ccache, it will pass -D options to clang even on
- // preprocessed inputs and configure concludes that -fPIC is not supported.
- Args.ClaimAllArgs(options::OPT_D);
- // Manually translate -O to -O2 and -O4 to -O3; let clang reject
- // others.
- if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
- if (A->getOption().matches(options::OPT_O4))
- CmdArgs.push_back("-O3");
- else if (A->getOption().matches(options::OPT_O) &&
- A->getValue()[0] == '\0')
- CmdArgs.push_back("-O2");
- else
- A->render(Args, CmdArgs);
- }
- // Don't warn about unused -flto. This can happen when we're preprocessing or
- // precompiling.
- Args.ClaimAllArgs(options::OPT_flto);
- Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
- if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
- CmdArgs.push_back("-pedantic");
- Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
- Args.AddLastArg(CmdArgs, options::OPT_w);
- // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
- // (-ansi is equivalent to -std=c89).
- //
- // If a std is supplied, only add -trigraphs if it follows the
- // option.
- if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
- if (Std->getOption().matches(options::OPT_ansi))
- if (types::isCXX(InputType))
- CmdArgs.push_back("-std=c++98");
- else
- CmdArgs.push_back("-std=c89");
- else
- Std->render(Args, CmdArgs);
- if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
- options::OPT_trigraphs))
- if (A != Std)
- A->render(Args, CmdArgs);
- } else {
- // Honor -std-default.
- //
- // FIXME: Clang doesn't correctly handle -std= when the input language
- // doesn't match. For the time being just ignore this for C++ inputs;
- // eventually we want to do all the standard defaulting here instead of
- // splitting it between the driver and clang -cc1.
- if (!types::isCXX(InputType))
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
- "-std=", /*Joined=*/true);
- else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32)
- CmdArgs.push_back("-std=c++11");
- Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
- }
- // Map the bizarre '-Wwrite-strings' flag to a more sensible
- // '-fconst-strings'; this better indicates its actual behavior.
- if (Args.hasFlag(options::OPT_Wwrite_strings, options::OPT_Wno_write_strings,
- false)) {
- // For perfect compatibility with GCC, we do this even in the presence of
- // '-w'. This flag names something other than a warning for GCC.
- CmdArgs.push_back("-fconst-strings");
- }
- // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
- // during C++ compilation, which it is by default. GCC keeps this define even
- // in the presence of '-w', match this behavior bug-for-bug.
- if (types::isCXX(InputType) &&
- Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
- true)) {
- CmdArgs.push_back("-fdeprecated-macro");
- }
- // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
- if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
- if (Asm->getOption().matches(options::OPT_fasm))
- CmdArgs.push_back("-fgnu-keywords");
- else
- CmdArgs.push_back("-fno-gnu-keywords");
- }
- if (ShouldDisableCFI(Args, getToolChain()))
- CmdArgs.push_back("-fno-dwarf2-cfi-asm");
- if (ShouldDisableDwarfDirectory(Args, getToolChain()))
- CmdArgs.push_back("-fno-dwarf-directory-asm");
- // Add in -fdebug-compilation-dir if necessary.
- addDebugCompDirArg(Args, CmdArgs);
- if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
- options::OPT_ftemplate_depth_EQ)) {
- CmdArgs.push_back("-ftemplate-depth");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
- CmdArgs.push_back("-fconstexpr-depth");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
- options::OPT_Wlarge_by_value_copy_def)) {
- if (A->getNumValues()) {
- StringRef bytes = A->getValue();
- CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
- } else
- CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
- }
- if (Args.hasArg(options::OPT_relocatable_pch))
- CmdArgs.push_back("-relocatable-pch");
- if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
- CmdArgs.push_back("-fconstant-string-class");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
- CmdArgs.push_back("-ftabstop");
- CmdArgs.push_back(A->getValue());
- }
- CmdArgs.push_back("-ferror-limit");
- if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
- CmdArgs.push_back(A->getValue());
- else
- CmdArgs.push_back("19");
- if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
- CmdArgs.push_back("-fmacro-backtrace-limit");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
- CmdArgs.push_back("-ftemplate-backtrace-limit");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
- CmdArgs.push_back("-fconstexpr-backtrace-limit");
- CmdArgs.push_back(A->getValue());
- }
- // Pass -fmessage-length=.
- CmdArgs.push_back("-fmessage-length");
- if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
- CmdArgs.push_back(A->getValue());
- } else {
- // If -fmessage-length=N was not specified, determine whether this is a
- // terminal and, if so, implicitly define -fmessage-length appropriately.
- unsigned N = llvm::sys::Process::StandardErrColumns();
- CmdArgs.push_back(Args.MakeArgString(Twine(N)));
- }
- if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
- CmdArgs.push_back("-fvisibility");
- CmdArgs.push_back(A->getValue());
- }
- Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
- Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
- // -fhosted is default.
- if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
- KernelOrKext)
- CmdArgs.push_back("-ffreestanding");
- // Forward -f (flag) options which we can pass directly.
- Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
- Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
- Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info);
- Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
- Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
- Args.AddLastArg(CmdArgs, options::OPT_faltivec);
- Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
- Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
- SanitizerArgs Sanitize(D, Args);
- Sanitize.addArgs(Args, CmdArgs);
- if (!Args.hasFlag(options::OPT_fsanitize_recover,
- options::OPT_fno_sanitize_recover,
- true))
- CmdArgs.push_back("-fno-sanitize-recover");
- // Report and error for -faltivec on anything other then PowerPC.
- if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
- if (!(getToolChain().getTriple().getArch() == llvm::Triple::ppc ||
- getToolChain().getTriple().getArch() == llvm::Triple::ppc64))
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "ppc/ppc64";
- if (getToolChain().SupportsProfiling())
- Args.AddLastArg(CmdArgs, options::OPT_pg);
- // -flax-vector-conversions is default.
- if (!Args.hasFlag(options::OPT_flax_vector_conversions,
- options::OPT_fno_lax_vector_conversions))
- CmdArgs.push_back("-fno-lax-vector-conversions");
- if (Args.getLastArg(options::OPT_fapple_kext))
- CmdArgs.push_back("-fapple-kext");
- if (Args.hasFlag(options::OPT_frewrite_includes,
- options::OPT_fno_rewrite_includes, false))
- CmdArgs.push_back("-frewrite-includes");
- Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
- Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
- Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
- Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
- Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
- if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
- CmdArgs.push_back("-ftrapv-handler");
- CmdArgs.push_back(A->getValue());
- }
- Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
- // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
- // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
- if (Arg *A = Args.getLastArg(options::OPT_fwrapv,
- options::OPT_fno_wrapv)) {
- if (A->getOption().matches(options::OPT_fwrapv))
- CmdArgs.push_back("-fwrapv");
- } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
- options::OPT_fno_strict_overflow)) {
- if (A->getOption().matches(options::OPT_fno_strict_overflow))
- CmdArgs.push_back("-fwrapv");
- }
- Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
- Args.AddLastArg(CmdArgs, options::OPT_funroll_loops);
- Args.AddLastArg(CmdArgs, options::OPT_pthread);
- // -stack-protector=0 is default.
- unsigned StackProtectorLevel = 0;
- if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
- options::OPT_fstack_protector_all,
- options::OPT_fstack_protector)) {
- if (A->getOption().matches(options::OPT_fstack_protector))
- StackProtectorLevel = 1;
- else if (A->getOption().matches(options::OPT_fstack_protector_all))
- StackProtectorLevel = 2;
- } else {
- StackProtectorLevel =
- getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
- }
- if (StackProtectorLevel) {
- CmdArgs.push_back("-stack-protector");
- CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
- }
- // --param ssp-buffer-size=
- for (arg_iterator it = Args.filtered_begin(options::OPT__param),
- ie = Args.filtered_end(); it != ie; ++it) {
- StringRef Str((*it)->getValue());
- if (Str.startswith("ssp-buffer-size=")) {
- if (StackProtectorLevel) {
- CmdArgs.push_back("-stack-protector-buffer-size");
- // FIXME: Verify the argument is a valid integer.
- CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
- }
- (*it)->claim();
- }
- }
- // Translate -mstackrealign
- if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
- false)) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-force-align-stack");
- }
- if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign,
- false)) {
- CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
- }
- if (Args.hasArg(options::OPT_mstack_alignment)) {
- StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
- CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
- }
- // -mkernel implies -mstrict-align; don't add the redundant option.
- if (Args.hasArg(options::OPT_mstrict_align) && !KernelOrKext) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-arm-strict-align");
- }
- // Forward -f options with positive and negative forms; we translate
- // these by hand.
- if (Args.hasArg(options::OPT_mkernel)) {
- if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
- CmdArgs.push_back("-fapple-kext");
- if (!Args.hasArg(options::OPT_fbuiltin))
- CmdArgs.push_back("-fno-builtin");
- Args.ClaimAllArgs(options::OPT_fno_builtin);
- }
- // -fbuiltin is default.
- else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
- CmdArgs.push_back("-fno-builtin");
- if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
- options::OPT_fno_assume_sane_operator_new))
- CmdArgs.push_back("-fno-assume-sane-operator-new");
- // -fblocks=0 is default.
- if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
- getToolChain().IsBlocksDefault()) ||
- (Args.hasArg(options::OPT_fgnu_runtime) &&
- Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
- !Args.hasArg(options::OPT_fno_blocks))) {
- CmdArgs.push_back("-fblocks");
- if (!Args.hasArg(options::OPT_fgnu_runtime) &&
- !getToolChain().hasBlocksRuntime())
- CmdArgs.push_back("-fblocks-runtime-optional");
- }
- // -fmodules enables modules (off by default). However, for C++/Objective-C++,
- // users must also pass -fcxx-modules. The latter flag will disappear once the
- // modules implementation is solid for C++/Objective-C++ programs as well.
- if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
- bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
- options::OPT_fno_cxx_modules,
- false);
- if (AllowedInCXX || !types::isCXX(InputType))
- CmdArgs.push_back("-fmodules");
- }
- // -faccess-control is default.
- if (Args.hasFlag(options::OPT_fno_access_control,
- options::OPT_faccess_control,
- false))
- CmdArgs.push_back("-fno-access-control");
- // -felide-constructors is the default.
- if (Args.hasFlag(options::OPT_fno_elide_constructors,
- options::OPT_felide_constructors,
- false))
- CmdArgs.push_back("-fno-elide-constructors");
- // -frtti is default.
- if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
- KernelOrKext) {
- CmdArgs.push_back("-fno-rtti");
- // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
- if (Sanitize.sanitizesVptr()) {
- std::string NoRttiArg =
- Args.getLastArg(options::OPT_mkernel,
- options::OPT_fapple_kext,
- options::OPT_fno_rtti)->getAsString(Args);
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << "-fsanitize=vptr" << NoRttiArg;
- }
- }
- // -fshort-enums=0 is default for all architectures except Hexagon.
- if (Args.hasFlag(options::OPT_fshort_enums,
- options::OPT_fno_short_enums,
- getToolChain().getTriple().getArch() ==
- llvm::Triple::hexagon))
- CmdArgs.push_back("-fshort-enums");
- // -fsigned-char is default.
- if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
- isSignedCharDefault(getToolChain().getTriple())))
- CmdArgs.push_back("-fno-signed-char");
- // -fthreadsafe-static is default.
- if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
- options::OPT_fno_threadsafe_statics))
- CmdArgs.push_back("-fno-threadsafe-statics");
- // -fuse-cxa-atexit is default.
- if (!Args.hasFlag(options::OPT_fuse_cxa_atexit,
- options::OPT_fno_use_cxa_atexit,
- getToolChain().getTriple().getOS() != llvm::Triple::Cygwin &&
- getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
- getToolChain().getTriple().getArch() != llvm::Triple::hexagon) ||
- KernelOrKext)
- CmdArgs.push_back("-fno-use-cxa-atexit");
- // -fms-extensions=0 is default.
- if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
- getToolChain().getTriple().getOS() == llvm::Triple::Win32))
- CmdArgs.push_back("-fms-extensions");
- // -fms-inline-asm.
- if (Args.hasArg(options::OPT_fenable_experimental_ms_inline_asm))
- CmdArgs.push_back("-fenable-experimental-ms-inline-asm");
- // -fms-compatibility=0 is default.
- if (Args.hasFlag(options::OPT_fms_compatibility,
- options::OPT_fno_ms_compatibility,
- (getToolChain().getTriple().getOS() == llvm::Triple::Win32 &&
- Args.hasFlag(options::OPT_fms_extensions,
- options::OPT_fno_ms_extensions,
- true))))
- CmdArgs.push_back("-fms-compatibility");
- // -fmsc-version=1300 is default.
- if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
- getToolChain().getTriple().getOS() == llvm::Triple::Win32) ||
- Args.hasArg(options::OPT_fmsc_version)) {
- StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version);
- if (msc_ver.empty())
- CmdArgs.push_back("-fmsc-version=1300");
- else
- CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver));
- }
- // -fborland-extensions=0 is default.
- if (Args.hasFlag(options::OPT_fborland_extensions,
- options::OPT_fno_borland_extensions, false))
- CmdArgs.push_back("-fborland-extensions");
- // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
- // needs it.
- if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
- options::OPT_fno_delayed_template_parsing,
- getToolChain().getTriple().getOS() == llvm::Triple::Win32))
- CmdArgs.push_back("-fdelayed-template-parsing");
- // -fgnu-keywords default varies depending on language; only pass if
- // specified.
- if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
- options::OPT_fno_gnu_keywords))
- A->render(Args, CmdArgs);
- if (Args.hasFlag(options::OPT_fgnu89_inline,
- options::OPT_fno_gnu89_inline,
- false))
- CmdArgs.push_back("-fgnu89-inline");
- if (Args.hasArg(options::OPT_fno_inline))
- CmdArgs.push_back("-fno-inline");
- if (Args.hasArg(options::OPT_fno_inline_functions))
- CmdArgs.push_back("-fno-inline-functions");
- ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
- // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
- // legacy is the default.
- if (objcRuntime.isNonFragile()) {
- if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
- options::OPT_fno_objc_legacy_dispatch,
- objcRuntime.isLegacyDispatchDefaultForArch(
- getToolChain().getTriple().getArch()))) {
- if (getToolChain().UseObjCMixedDispatch())
- CmdArgs.push_back("-fobjc-dispatch-method=mixed");
- else
- CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
- }
- }
- // -fobjc-default-synthesize-properties=1 is default. This only has an effect
- // if the nonfragile objc abi is used.
- if (getToolChain().IsObjCDefaultSynthPropertiesDefault()) {
- CmdArgs.push_back("-fobjc-default-synthesize-properties");
- }
- // -fencode-extended-block-signature=1 is default.
- if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
- CmdArgs.push_back("-fencode-extended-block-signature");
- }
-
- // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
- // NOTE: This logic is duplicated in ToolChains.cpp.
- bool ARC = isObjCAutoRefCount(Args);
- if (ARC) {
- getToolChain().CheckObjCARC();
- CmdArgs.push_back("-fobjc-arc");
- // FIXME: It seems like this entire block, and several around it should be
- // wrapped in isObjC, but for now we just use it here as this is where it
- // was being used previously.
- if (types::isCXX(InputType) && types::isObjC(InputType)) {
- if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
- CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
- else
- CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
- }
- // Allow the user to enable full exceptions code emission.
- // We define off for Objective-CC, on for Objective-C++.
- if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
- options::OPT_fno_objc_arc_exceptions,
- /*default*/ types::isCXX(InputType)))
- CmdArgs.push_back("-fobjc-arc-exceptions");
- }
- // -fobjc-infer-related-result-type is the default, except in the Objective-C
- // rewriter.
- if (rewriteKind != RK_None)
- CmdArgs.push_back("-fno-objc-infer-related-result-type");
- // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
- // takes precedence.
- const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
- if (!GCArg)
- GCArg = Args.getLastArg(options::OPT_fobjc_gc);
- if (GCArg) {
- if (ARC) {
- D.Diag(diag::err_drv_objc_gc_arr)
- << GCArg->getAsString(Args);
- } else if (getToolChain().SupportsObjCGC()) {
- GCArg->render(Args, CmdArgs);
- } else {
- // FIXME: We should move this to a hard error.
- D.Diag(diag::warn_drv_objc_gc_unsupported)
- << GCArg->getAsString(Args);
- }
- }
- // Add exception args.
- addExceptionArgs(Args, InputType, getToolChain().getTriple(),
- KernelOrKext, objcRuntime, CmdArgs);
- if (getToolChain().UseSjLjExceptions())
- CmdArgs.push_back("-fsjlj-exceptions");
- // C++ "sane" operator new.
- if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
- options::OPT_fno_assume_sane_operator_new))
- CmdArgs.push_back("-fno-assume-sane-operator-new");
- // -fconstant-cfstrings is default, and may be subject to argument translation
- // on Darwin.
- if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
- options::OPT_fno_constant_cfstrings) ||
- !Args.hasFlag(options::OPT_mconstant_cfstrings,
- options::OPT_mno_constant_cfstrings))
- CmdArgs.push_back("-fno-constant-cfstrings");
- // -fshort-wchar default varies depending on platform; only
- // pass if specified.
- if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
- A->render(Args, CmdArgs);
- // -fno-pascal-strings is default, only pass non-default. If the tool chain
- // happened to translate to -mpascal-strings, we want to back translate here.
- //
- // FIXME: This is gross; that translation should be pulled from the
- // tool chain.
- if (Args.hasFlag(options::OPT_fpascal_strings,
- options::OPT_fno_pascal_strings,
- false) ||
- Args.hasFlag(options::OPT_mpascal_strings,
- options::OPT_mno_pascal_strings,
- false))
- CmdArgs.push_back("-fpascal-strings");
- // Honor -fpack-struct= and -fpack-struct, if given. Note that
- // -fno-pack-struct doesn't apply to -fpack-struct=.
- if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
- std::string PackStructStr = "-fpack-struct=";
- PackStructStr += A->getValue();
- CmdArgs.push_back(Args.MakeArgString(PackStructStr));
- } else if (Args.hasFlag(options::OPT_fpack_struct,
- options::OPT_fno_pack_struct, false)) {
- CmdArgs.push_back("-fpack-struct=1");
- }
- if (Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) {
- if (!Args.hasArg(options::OPT_fcommon))
- CmdArgs.push_back("-fno-common");
- Args.ClaimAllArgs(options::OPT_fno_common);
- }
- // -fcommon is default, only pass non-default.
- else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
- CmdArgs.push_back("-fno-common");
- // -fsigned-bitfields is default, and clang doesn't yet support
- // -funsigned-bitfields.
- if (!Args.hasFlag(options::OPT_fsigned_bitfields,
- options::OPT_funsigned_bitfields))
- D.Diag(diag::warn_drv_clang_unsupported)
- << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
- // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
- if (!Args.hasFlag(options::OPT_ffor_scope,
- options::OPT_fno_for_scope))
- D.Diag(diag::err_drv_clang_unsupported)
- << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
- // -fcaret-diagnostics is default.
- if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
- options::OPT_fno_caret_diagnostics, true))
- CmdArgs.push_back("-fno-caret-diagnostics");
- // -fdiagnostics-fixit-info is default, only pass non-default.
- if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
- options::OPT_fno_diagnostics_fixit_info))
- CmdArgs.push_back("-fno-diagnostics-fixit-info");
- // Enable -fdiagnostics-show-option by default.
- if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
- options::OPT_fno_diagnostics_show_option))
- CmdArgs.push_back("-fdiagnostics-show-option");
- if (const Arg *A =
- Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
- CmdArgs.push_back("-fdiagnostics-show-category");
- CmdArgs.push_back(A->getValue());
- }
- if (const Arg *A =
- Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
- CmdArgs.push_back("-fdiagnostics-format");
- CmdArgs.push_back(A->getValue());
- }
- if (Arg *A = Args.getLastArg(
- options::OPT_fdiagnostics_show_note_include_stack,
- options::OPT_fno_diagnostics_show_note_include_stack)) {
- if (A->getOption().matches(
- options::OPT_fdiagnostics_show_note_include_stack))
- CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
- else
- CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
- }
- // Color diagnostics are the default, unless the terminal doesn't support
- // them.
- if (Args.hasFlag(options::OPT_fcolor_diagnostics,
- options::OPT_fno_color_diagnostics,
- llvm::sys::Process::StandardErrHasColors()))
- CmdArgs.push_back("-fcolor-diagnostics");
- if (!Args.hasFlag(options::OPT_fshow_source_location,
- options::OPT_fno_show_source_location))
- CmdArgs.push_back("-fno-show-source-location");
- if (!Args.hasFlag(options::OPT_fshow_column,
- options::OPT_fno_show_column,
- true))
- CmdArgs.push_back("-fno-show-column");
- if (!Args.hasFlag(options::OPT_fspell_checking,
- options::OPT_fno_spell_checking))
- CmdArgs.push_back("-fno-spell-checking");
- // -fno-asm-blocks is default.
- if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
- false))
- CmdArgs.push_back("-fasm-blocks");
- // -fvectorize is default.
- if (Args.hasFlag(options::OPT_fvectorize,
- options::OPT_fno_vectorize, true)) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-vectorize-loops");
- }
- // -fno-slp-vectorize is default.
- if (Args.hasFlag(options::OPT_fslp_vectorize,
- options::OPT_fno_slp_vectorize, false)) {
- CmdArgs.push_back("-backend-option");
- CmdArgs.push_back("-vectorize");
- }
- if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
- A->render(Args, CmdArgs);
- // -fdollars-in-identifiers default varies depending on platform and
- // language; only pass if specified.
- if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
- options::OPT_fno_dollars_in_identifiers)) {
- if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
- CmdArgs.push_back("-fdollars-in-identifiers");
- else
- CmdArgs.push_back("-fno-dollars-in-identifiers");
- }
- // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
- // practical purposes.
- if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
- options::OPT_fno_unit_at_a_time)) {
- if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
- D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
- }
- if (Args.hasFlag(options::OPT_fapple_pragma_pack,
- options::OPT_fno_apple_pragma_pack, false))
- CmdArgs.push_back("-fapple-pragma-pack");
- // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
- //
- // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
- #if 0
- if (getToolChain().getTriple().isOSDarwin() &&
- (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
- getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
- if (!Args.hasArg(options::OPT_fbuiltin_strcat))
- CmdArgs.push_back("-fno-builtin-strcat");
- if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
- CmdArgs.push_back("-fno-builtin-strcpy");
- }
- #endif
- // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
- if (Arg *A = Args.getLastArg(options::OPT_traditional,
- options::OPT_traditional_cpp)) {
- if (isa<PreprocessJobAction>(JA))
- CmdArgs.push_back("-traditional-cpp");
- else
- D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
- }
- Args.AddLastArg(CmdArgs, options::OPT_dM);
- Args.AddLastArg(CmdArgs, options::OPT_dD);
-
- // Handle serialized diagnostics.
- if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
- CmdArgs.push_back("-serialize-diagnostic-file");
- CmdArgs.push_back(Args.MakeArgString(A->getValue()));
- }
- if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
- CmdArgs.push_back("-fretain-comments-from-system-headers");
- // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
- // parser.
- Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
- for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
- ie = Args.filtered_end(); it != ie; ++it) {
- (*it)->claim();
- // We translate this by hand to the -cc1 argument, since nightly test uses
- // it and developers have been trained to spell it with -mllvm.
- if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns")
- CmdArgs.push_back("-disable-llvm-optzns");
- else
- (*it)->render(Args, CmdArgs);
- }
- if (Output.getType() == types::TY_Dependencies) {
- // Handled with other dependency code.
- } else if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back("-x");
- if (Args.hasArg(options::OPT_rewrite_objc))
- CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
- else
- CmdArgs.push_back(types::getTypeName(II.getType()));
- if (II.isFilename())
- CmdArgs.push_back(II.getFilename());
- else
- II.getInputArg().renderAsInput(Args, CmdArgs);
- }
- Args.AddAllArgs(CmdArgs, options::OPT_undef);
- const char *Exec = getToolChain().getDriver().getClangProgramPath();
- // Optionally embed the -cc1 level arguments into the debug info, for build
- // analysis.
- if (getToolChain().UseDwarfDebugFlags()) {
- ArgStringList OriginalArgs;
- for (ArgList::const_iterator it = Args.begin(),
- ie = Args.end(); it != ie; ++it)
- (*it)->render(Args, OriginalArgs);
- SmallString<256> Flags;
- Flags += Exec;
- for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
- Flags += " ";
- Flags += OriginalArgs[i];
- }
- CmdArgs.push_back("-dwarf-debug-flags");
- CmdArgs.push_back(Args.MakeArgString(Flags.str()));
- }
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- if (Arg *A = Args.getLastArg(options::OPT_pg))
- if (Args.hasArg(options::OPT_fomit_frame_pointer))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << "-fomit-frame-pointer" << A->getAsString(Args);
- // Claim some arguments which clang supports automatically.
- // -fpch-preprocess is used with gcc to add a special marker in the output to
- // include the PCH file. Clang's PTH solution is completely transparent, so we
- // do not need to deal with it at all.
- Args.ClaimAllArgs(options::OPT_fpch_preprocess);
- // Claim some arguments which clang doesn't support, but we don't
- // care to warn the user about.
- Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
- Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
- // Disable warnings for clang -E -use-gold-plugin -emit-llvm foo.c
- Args.ClaimAllArgs(options::OPT_use_gold_plugin);
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- }
- void ClangAs::AddARMTargetArgs(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
- llvm::Triple Triple = getToolChain().getTriple();
- // Set the CPU based on -march= and -mcpu=.
- CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString(getARMTargetCPU(Args, Triple)));
- // Honor -mfpu=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
- addFPUArgs(D, A, Args, CmdArgs);
- // Honor -mfpmath=.
- if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ))
- addFPMathArgs(D, A, Args, CmdArgs, getARMTargetCPU(Args, Triple));
- }
- /// Add options related to the Objective-C runtime/ABI.
- ///
- /// Returns true if the runtime is non-fragile.
- ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
- ArgStringList &cmdArgs,
- RewriteKind rewriteKind) const {
- // Look for the controlling runtime option.
- Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime,
- options::OPT_fgnu_runtime,
- options::OPT_fobjc_runtime_EQ);
- // Just forward -fobjc-runtime= to the frontend. This supercedes
- // options about fragility.
- if (runtimeArg &&
- runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
- ObjCRuntime runtime;
- StringRef value = runtimeArg->getValue();
- if (runtime.tryParse(value)) {
- getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
- << value;
- }
- runtimeArg->render(args, cmdArgs);
- return runtime;
- }
- // Otherwise, we'll need the ABI "version". Version numbers are
- // slightly confusing for historical reasons:
- // 1 - Traditional "fragile" ABI
- // 2 - Non-fragile ABI, version 1
- // 3 - Non-fragile ABI, version 2
- unsigned objcABIVersion = 1;
- // If -fobjc-abi-version= is present, use that to set the version.
- if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
- StringRef value = abiArg->getValue();
- if (value == "1")
- objcABIVersion = 1;
- else if (value == "2")
- objcABIVersion = 2;
- else if (value == "3")
- objcABIVersion = 3;
- else
- getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
- << value;
- } else {
- // Otherwise, determine if we are using the non-fragile ABI.
- bool nonFragileABIIsDefault =
- (rewriteKind == RK_NonFragile ||
- (rewriteKind == RK_None &&
- getToolChain().IsObjCNonFragileABIDefault()));
- if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
- options::OPT_fno_objc_nonfragile_abi,
- nonFragileABIIsDefault)) {
- // Determine the non-fragile ABI version to use.
- #ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
- unsigned nonFragileABIVersion = 1;
- #else
- unsigned nonFragileABIVersion = 2;
- #endif
- if (Arg *abiArg = args.getLastArg(
- options::OPT_fobjc_nonfragile_abi_version_EQ)) {
- StringRef value = abiArg->getValue();
- if (value == "1")
- nonFragileABIVersion = 1;
- else if (value == "2")
- nonFragileABIVersion = 2;
- else
- getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
- << value;
- }
- objcABIVersion = 1 + nonFragileABIVersion;
- } else {
- objcABIVersion = 1;
- }
- }
- // We don't actually care about the ABI version other than whether
- // it's non-fragile.
- bool isNonFragile = objcABIVersion != 1;
- // If we have no runtime argument, ask the toolchain for its default runtime.
- // However, the rewriter only really supports the Mac runtime, so assume that.
- ObjCRuntime runtime;
- if (!runtimeArg) {
- switch (rewriteKind) {
- case RK_None:
- runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
- break;
- case RK_Fragile:
- runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
- break;
- case RK_NonFragile:
- runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
- break;
- }
- // -fnext-runtime
- } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
- // On Darwin, make this use the default behavior for the toolchain.
- if (getToolChain().getTriple().isOSDarwin()) {
- runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
- // Otherwise, build for a generic macosx port.
- } else {
- runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
- }
- // -fgnu-runtime
- } else {
- assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
- // Legacy behaviour is to target the gnustep runtime if we are i
- // non-fragile mode or the GCC runtime in fragile mode.
- if (isNonFragile)
- runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
- else
- runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
- }
- cmdArgs.push_back(args.MakeArgString(
- "-fobjc-runtime=" + runtime.getAsString()));
- return runtime;
- }
- void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- assert(Inputs.size() == 1 && "Unexpected number of inputs.");
- const InputInfo &Input = Inputs[0];
- // Don't warn about "clang -w -c foo.s"
- Args.ClaimAllArgs(options::OPT_w);
- // and "clang -emit-llvm -c foo.s"
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- // and "clang -use-gold-plugin -c foo.s"
- Args.ClaimAllArgs(options::OPT_use_gold_plugin);
- // Invoke ourselves in -cc1as mode.
- //
- // FIXME: Implement custom jobs for internal actions.
- CmdArgs.push_back("-cc1as");
- // Add the "effective" target triple.
- CmdArgs.push_back("-triple");
- std::string TripleStr =
- getToolChain().ComputeEffectiveClangTriple(Args, Input.getType());
- CmdArgs.push_back(Args.MakeArgString(TripleStr));
- // Set the output mode, we currently only expect to be used as a real
- // assembler.
- CmdArgs.push_back("-filetype");
- CmdArgs.push_back("obj");
- // Set the main file name, so that debug info works even with
- // -save-temps or preprocessed assembly.
- CmdArgs.push_back("-main-file-name");
- CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs));
- if (UseRelaxAll(C, Args))
- CmdArgs.push_back("-relax-all");
- // Add target specific cpu and features flags.
- switch(getToolChain().getTriple().getArch()) {
- default:
- break;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- AddARMTargetArgs(Args, CmdArgs);
- break;
- }
- // Ignore explicit -force_cpusubtype_ALL option.
- (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
- // Determine the original source input.
- const Action *SourceAction = &JA;
- while (SourceAction->getKind() != Action::InputClass) {
- assert(!SourceAction->getInputs().empty() && "unexpected root action!");
- SourceAction = SourceAction->getInputs()[0];
- }
- // Forward -g and handle debug info related flags, assuming we are dealing
- // with an actual assembly file.
- if (SourceAction->getType() == types::TY_Asm ||
- SourceAction->getType() == types::TY_PP_Asm) {
- Args.ClaimAllArgs(options::OPT_g_Group);
- if (Arg *A = Args.getLastArg(options::OPT_g_Group))
- if (!A->getOption().matches(options::OPT_g0))
- CmdArgs.push_back("-g");
- // Add the -fdebug-compilation-dir flag if needed.
- addDebugCompDirArg(Args, CmdArgs);
- }
- // Optionally embed the -cc1as level arguments into the debug info, for build
- // analysis.
- if (getToolChain().UseDwarfDebugFlags()) {
- ArgStringList OriginalArgs;
- for (ArgList::const_iterator it = Args.begin(),
- ie = Args.end(); it != ie; ++it)
- (*it)->render(Args, OriginalArgs);
- SmallString<256> Flags;
- const char *Exec = getToolChain().getDriver().getClangProgramPath();
- Flags += Exec;
- for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
- Flags += " ";
- Flags += OriginalArgs[i];
- }
- CmdArgs.push_back("-dwarf-debug-flags");
- CmdArgs.push_back(Args.MakeArgString(Flags.str()));
- }
- // FIXME: Add -static support, once we have it.
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
- assert(Output.isFilename() && "Unexpected lipo output.");
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- assert(Input.isFilename() && "Invalid input.");
- CmdArgs.push_back(Input.getFilename());
- const char *Exec = getToolChain().getDriver().getClangProgramPath();
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- for (ArgList::const_iterator
- it = Args.begin(), ie = Args.end(); it != ie; ++it) {
- Arg *A = *it;
- if (forwardToGCC(A->getOption())) {
- // Don't forward any -g arguments to assembly steps.
- if (isa<AssembleJobAction>(JA) &&
- A->getOption().matches(options::OPT_g_Group))
- continue;
- // It is unfortunate that we have to claim here, as this means
- // we will basically never report anything interesting for
- // platforms using a generic gcc, even if we are just using gcc
- // to get to the assembler.
- A->claim();
- A->render(Args, CmdArgs);
- }
- }
- RenderExtraToolArgs(JA, CmdArgs);
- // If using a driver driver, force the arch.
- llvm::Triple::ArchType Arch = getToolChain().getArch();
- if (getToolChain().getTriple().isOSDarwin()) {
- CmdArgs.push_back("-arch");
- // FIXME: Remove these special cases.
- if (Arch == llvm::Triple::ppc)
- CmdArgs.push_back("ppc");
- else if (Arch == llvm::Triple::ppc64)
- CmdArgs.push_back("ppc64");
- else
- CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
- }
- // Try to force gcc to match the tool chain we want, if we recognize
- // the arch.
- //
- // FIXME: The triple class should directly provide the information we want
- // here.
- if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
- CmdArgs.push_back("-m32");
- else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86_64)
- CmdArgs.push_back("-m64");
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Unexpected output");
- CmdArgs.push_back("-fsyntax-only");
- }
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- // Only pass -x if gcc will understand it; otherwise hope gcc
- // understands the suffix correctly. The main use case this would go
- // wrong in is for linker inputs if they happened to have an odd
- // suffix; really the only way to get this to happen is a command
- // like '-x foobar a.c' which will treat a.c like a linker input.
- //
- // FIXME: For the linker case specifically, can we safely convert
- // inputs into '-Wl,' options?
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- // Don't try to pass LLVM or AST inputs to a generic gcc.
- if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
- II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
- D.Diag(diag::err_drv_no_linker_llvm_support)
- << getToolChain().getTripleString();
- else if (II.getType() == types::TY_AST)
- D.Diag(diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
- if (types::canTypeBeUserSpecified(II.getType())) {
- CmdArgs.push_back("-x");
- CmdArgs.push_back(types::getTypeName(II.getType()));
- }
- if (II.isFilename())
- CmdArgs.push_back(II.getFilename());
- else {
- const Arg &A = II.getInputArg();
- // Reverse translate some rewritten options.
- if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
- CmdArgs.push_back("-lstdc++");
- continue;
- }
- // Don't render as input, we need gcc to do the translations.
- A.render(Args, CmdArgs);
- }
- }
- const std::string customGCCName = D.getCCCGenericGCCName();
- const char *GCCName;
- if (!customGCCName.empty())
- GCCName = customGCCName.c_str();
- else if (D.CCCIsCXX) {
- GCCName = "g++";
- } else
- GCCName = "gcc";
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- CmdArgs.push_back("-E");
- }
- void gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- // The type is good enough.
- }
- void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- const Driver &D = getToolChain().getDriver();
- // If -flto, etc. are present then make sure not to force assembly output.
- if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
- JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
- CmdArgs.push_back("-c");
- else {
- if (JA.getType() != types::TY_PP_Asm)
- D.Diag(diag::err_drv_invalid_gcc_output_type)
- << getTypeName(JA.getType());
- CmdArgs.push_back("-S");
- }
- }
- void gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- CmdArgs.push_back("-c");
- }
- void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- // The types are (hopefully) good enough.
- }
- // Hexagon tools start.
- void hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- }
- void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- std::string MarchString = "-march=";
- MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
- CmdArgs.push_back(Args.MakeArgString(MarchString));
- RenderExtraToolArgs(JA, CmdArgs);
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Unexpected output");
- CmdArgs.push_back("-fsyntax-only");
- }
- std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
- if (!SmallDataThreshold.empty())
- CmdArgs.push_back(
- Args.MakeArgString(std::string("-G") + SmallDataThreshold));
- Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- // Only pass -x if gcc will understand it; otherwise hope gcc
- // understands the suffix correctly. The main use case this would go
- // wrong in is for linker inputs if they happened to have an odd
- // suffix; really the only way to get this to happen is a command
- // like '-x foobar a.c' which will treat a.c like a linker input.
- //
- // FIXME: For the linker case specifically, can we safely convert
- // inputs into '-Wl,' options?
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- // Don't try to pass LLVM or AST inputs to a generic gcc.
- if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
- II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
- D.Diag(clang::diag::err_drv_no_linker_llvm_support)
- << getToolChain().getTripleString();
- else if (II.getType() == types::TY_AST)
- D.Diag(clang::diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
- if (II.isFilename())
- CmdArgs.push_back(II.getFilename());
- else
- // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
- II.getInputArg().render(Args, CmdArgs);
- }
- const char *GCCName = "hexagon-as";
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {
- // The types are (hopefully) good enough.
- }
- void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const toolchains::Hexagon_TC& ToolChain =
- static_cast<const toolchains::Hexagon_TC&>(getToolChain());
- const Driver &D = ToolChain.getDriver();
- ArgStringList CmdArgs;
- //----------------------------------------------------------------------------
- //
- //----------------------------------------------------------------------------
- bool hasStaticArg = Args.hasArg(options::OPT_static);
- bool buildingLib = Args.hasArg(options::OPT_shared);
- bool buildPIE = Args.hasArg(options::OPT_pie);
- bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
- bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
- bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
- bool useShared = buildingLib && !hasStaticArg;
- //----------------------------------------------------------------------------
- // Silence warnings for various options
- //----------------------------------------------------------------------------
- Args.ClaimAllArgs(options::OPT_g_Group);
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
- // handled somewhere else.
- Args.ClaimAllArgs(options::OPT_static_libgcc);
- //----------------------------------------------------------------------------
- //
- //----------------------------------------------------------------------------
- for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
- e = ToolChain.ExtraOpts.end();
- i != e; ++i)
- CmdArgs.push_back(i->c_str());
- std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
- CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
- if (buildingLib) {
- CmdArgs.push_back("-shared");
- CmdArgs.push_back("-call_shared"); // should be the default, but doing as
- // hexagon-gcc does
- }
- if (hasStaticArg)
- CmdArgs.push_back("-static");
- if (buildPIE && !buildingLib)
- CmdArgs.push_back("-pie");
- std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
- if (!SmallDataThreshold.empty()) {
- CmdArgs.push_back(
- Args.MakeArgString(std::string("-G") + SmallDataThreshold));
- }
- //----------------------------------------------------------------------------
- //
- //----------------------------------------------------------------------------
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- const std::string MarchSuffix = "/" + MarchString;
- const std::string G0Suffix = "/G0";
- const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
- const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
- + "/";
- const std::string StartFilesDir = RootDir
- + "hexagon/lib"
- + (buildingLib
- ? MarchG0Suffix : MarchSuffix);
- //----------------------------------------------------------------------------
- // moslib
- //----------------------------------------------------------------------------
- std::vector<std::string> oslibs;
- bool hasStandalone= false;
- for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
- ie = Args.filtered_end(); it != ie; ++it) {
- (*it)->claim();
- oslibs.push_back((*it)->getValue());
- hasStandalone = hasStandalone || (oslibs.back() == "standalone");
- }
- if (oslibs.empty()) {
- oslibs.push_back("standalone");
- hasStandalone = true;
- }
- //----------------------------------------------------------------------------
- // Start Files
- //----------------------------------------------------------------------------
- if (incStdLib && incStartFiles) {
- if (!buildingLib) {
- if (hasStandalone) {
- CmdArgs.push_back(
- Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
- }
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
- }
- std::string initObj = useShared ? "/initS.o" : "/init.o";
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
- }
- //----------------------------------------------------------------------------
- // Library Search Paths
- //----------------------------------------------------------------------------
- const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
- for (ToolChain::path_list::const_iterator
- i = LibPaths.begin(),
- e = LibPaths.end();
- i != e;
- ++i)
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
- //----------------------------------------------------------------------------
- //
- //----------------------------------------------------------------------------
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- Args.AddAllArgs(CmdArgs, options::OPT_s);
- Args.AddAllArgs(CmdArgs, options::OPT_t);
- Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- //----------------------------------------------------------------------------
- // Libraries
- //----------------------------------------------------------------------------
- if (incStdLib && incDefLibs) {
- if (D.CCCIsCXX) {
- ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lm");
- }
- CmdArgs.push_back("--start-group");
- if (!buildingLib) {
- for(std::vector<std::string>::iterator i = oslibs.begin(),
- e = oslibs.end(); i != e; ++i)
- CmdArgs.push_back(Args.MakeArgString("-l" + *i));
- CmdArgs.push_back("-lc");
- }
- CmdArgs.push_back("-lgcc");
- CmdArgs.push_back("--end-group");
- }
- //----------------------------------------------------------------------------
- // End files
- //----------------------------------------------------------------------------
- if (incStdLib && incStartFiles) {
- std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
- }
- std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
- C.addCommand(
- new Command(
- JA, *this,
- Args.MakeArgString(Linker), CmdArgs));
- }
- // Hexagon tools end.
- llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
- // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
- // archs which Darwin doesn't use.
- // The matching this routine does is fairly pointless, since it is neither the
- // complete architecture list, nor a reasonable subset. The problem is that
- // historically the driver driver accepts this and also ties its -march=
- // handling to the architecture name, so we need to be careful before removing
- // support for it.
- // This code must be kept in sync with Clang's Darwin specific argument
- // translation.
- return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
- .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
- .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
- .Case("ppc64", llvm::Triple::ppc64)
- .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
- .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
- llvm::Triple::x86)
- .Case("x86_64", llvm::Triple::x86_64)
- // This is derived from the driver driver.
- .Cases("arm", "armv4t", "armv5", "armv6", llvm::Triple::arm)
- .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", llvm::Triple::arm)
- .Case("r600", llvm::Triple::r600)
- .Case("nvptx", llvm::Triple::nvptx)
- .Case("nvptx64", llvm::Triple::nvptx64)
- .Case("amdil", llvm::Triple::amdil)
- .Case("spir", llvm::Triple::spir)
- .Default(llvm::Triple::UnknownArch);
- }
- const char *Clang::getBaseInputName(const ArgList &Args,
- const InputInfoList &Inputs) {
- return Args.MakeArgString(
- llvm::sys::path::filename(Inputs[0].getBaseInput()));
- }
- const char *Clang::getBaseInputStem(const ArgList &Args,
- const InputInfoList &Inputs) {
- const char *Str = getBaseInputName(Args, Inputs);
- if (const char *End = strrchr(Str, '.'))
- return Args.MakeArgString(std::string(Str, End));
- return Str;
- }
- const char *Clang::getDependencyFileName(const ArgList &Args,
- const InputInfoList &Inputs) {
- // FIXME: Think about this more.
- std::string Res;
- if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
- std::string Str(OutputOpt->getValue());
- Res = Str.substr(0, Str.rfind('.'));
- } else {
- Res = getBaseInputStem(Args, Inputs);
- }
- return Args.MakeArgString(Res + ".d");
- }
- void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- assert(Inputs.size() == 1 && "Unexpected number of inputs.");
- const InputInfo &Input = Inputs[0];
- // Determine the original source input.
- const Action *SourceAction = &JA;
- while (SourceAction->getKind() != Action::InputClass) {
- assert(!SourceAction->getInputs().empty() && "unexpected root action!");
- SourceAction = SourceAction->getInputs()[0];
- }
- // Forward -g, assuming we are dealing with an actual assembly file.
- if (SourceAction->getType() == types::TY_Asm ||
- SourceAction->getType() == types::TY_PP_Asm) {
- if (Args.hasArg(options::OPT_gstabs))
- CmdArgs.push_back("--gstabs");
- else if (Args.hasArg(options::OPT_g_Group))
- CmdArgs.push_back("-g");
- }
- // Derived from asm spec.
- AddDarwinArch(Args, CmdArgs);
- // Use -force_cpusubtype_ALL on x86 by default.
- if (getToolChain().getTriple().getArch() == llvm::Triple::x86 ||
- getToolChain().getTriple().getArch() == llvm::Triple::x86_64 ||
- Args.hasArg(options::OPT_force__cpusubtype__ALL))
- CmdArgs.push_back("-force_cpusubtype_ALL");
- if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
- (((Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) &&
- (!getDarwinToolChain().isTargetIPhoneOS() ||
- getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
- Args.hasArg(options::OPT_static)))
- CmdArgs.push_back("-static");
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- assert(Output.isFilename() && "Unexpected lipo output.");
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- assert(Input.isFilename() && "Invalid input.");
- CmdArgs.push_back(Input.getFilename());
- // asm_final spec is empty.
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void darwin::DarwinTool::anchor() {}
- void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
- ArgStringList &CmdArgs) const {
- StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
- // Derived from darwin_arch spec.
- CmdArgs.push_back("-arch");
- CmdArgs.push_back(Args.MakeArgString(ArchName));
- // FIXME: Is this needed anymore?
- if (ArchName == "arm")
- CmdArgs.push_back("-force_cpusubtype_ALL");
- }
- bool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const {
- // We only need to generate a temp path for LTO if we aren't compiling object
- // files. When compiling source files, we run 'dsymutil' after linking. We
- // don't run 'dsymutil' when compiling object files.
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
- if (it->getType() != types::TY_Object)
- return true;
- return false;
- }
- void darwin::Link::AddLinkArgs(Compilation &C,
- const ArgList &Args,
- ArgStringList &CmdArgs,
- const InputInfoList &Inputs) const {
- const Driver &D = getToolChain().getDriver();
- const toolchains::Darwin &DarwinTC = getDarwinToolChain();
- unsigned Version[3] = { 0, 0, 0 };
- if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
- bool HadExtra;
- if (!Driver::GetReleaseVersion(A->getValue(), Version[0],
- Version[1], Version[2], HadExtra) ||
- HadExtra)
- D.Diag(diag::err_drv_invalid_version_number)
- << A->getAsString(Args);
- }
- // Newer linkers support -demangle, pass it if supported and not disabled by
- // the user.
- if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) {
- // Don't pass -demangle to ld_classic.
- //
- // FIXME: This is a temporary workaround, ld should be handling this.
- bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 &&
- Args.hasArg(options::OPT_static));
- if (getToolChain().getArch() == llvm::Triple::x86) {
- for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker,
- options::OPT_Wl_COMMA),
- ie = Args.filtered_end(); it != ie; ++it) {
- const Arg *A = *it;
- for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
- if (StringRef(A->getValue(i)) == "-kext")
- UsesLdClassic = true;
- }
- }
- if (!UsesLdClassic)
- CmdArgs.push_back("-demangle");
- }
- // If we are using LTO, then automatically create a temporary file path for
- // the linker to use, so that it's lifetime will extend past a possible
- // dsymutil step.
- if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
- const char *TmpPath = C.getArgs().MakeArgString(
- D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
- C.addTempFile(TmpPath);
- CmdArgs.push_back("-object_path_lto");
- CmdArgs.push_back(TmpPath);
- }
- // Derived from the "link" spec.
- Args.AddAllArgs(CmdArgs, options::OPT_static);
- if (!Args.hasArg(options::OPT_static))
- CmdArgs.push_back("-dynamic");
- if (Args.hasArg(options::OPT_fgnu_runtime)) {
- // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
- // here. How do we wish to handle such things?
- }
- if (!Args.hasArg(options::OPT_dynamiclib)) {
- AddDarwinArch(Args, CmdArgs);
- // FIXME: Why do this only on this path?
- Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
- Args.AddLastArg(CmdArgs, options::OPT_bundle);
- Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
- Args.AddAllArgs(CmdArgs, options::OPT_client__name);
- Arg *A;
- if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
- (A = Args.getLastArg(options::OPT_current__version)) ||
- (A = Args.getLastArg(options::OPT_install__name)))
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << A->getAsString(Args) << "-dynamiclib";
- Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
- Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
- Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
- } else {
- CmdArgs.push_back("-dylib");
- Arg *A;
- if ((A = Args.getLastArg(options::OPT_bundle)) ||
- (A = Args.getLastArg(options::OPT_bundle__loader)) ||
- (A = Args.getLastArg(options::OPT_client__name)) ||
- (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
- (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
- (A = Args.getLastArg(options::OPT_private__bundle)))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << A->getAsString(Args) << "-dynamiclib";
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
- "-dylib_compatibility_version");
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
- "-dylib_current_version");
- AddDarwinArch(Args, CmdArgs);
- Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
- "-dylib_install_name");
- }
- Args.AddLastArg(CmdArgs, options::OPT_all__load);
- Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
- Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
- if (DarwinTC.isTargetIPhoneOS())
- Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
- Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
- Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
- Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
- Args.AddLastArg(CmdArgs, options::OPT_dynamic);
- Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
- Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
- Args.AddAllArgs(CmdArgs, options::OPT_force__load);
- Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
- Args.AddAllArgs(CmdArgs, options::OPT_image__base);
- Args.AddAllArgs(CmdArgs, options::OPT_init);
- // Add the deployment target.
- VersionTuple TargetVersion = DarwinTC.getTargetVersion();
- // If we had an explicit -mios-simulator-version-min argument, honor that,
- // otherwise use the traditional deployment targets. We can't just check the
- // is-sim attribute because existing code follows this path, and the linker
- // may not handle the argument.
- //
- // FIXME: We may be able to remove this, once we can verify no one depends on
- // it.
- if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
- CmdArgs.push_back("-ios_simulator_version_min");
- else if (DarwinTC.isTargetIPhoneOS())
- CmdArgs.push_back("-iphoneos_version_min");
- else
- CmdArgs.push_back("-macosx_version_min");
- CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
- Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
- Args.AddLastArg(CmdArgs, options::OPT_multi__module);
- Args.AddLastArg(CmdArgs, options::OPT_single__module);
- Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
- Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
- if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
- options::OPT_fno_pie,
- options::OPT_fno_PIE)) {
- if (A->getOption().matches(options::OPT_fpie) ||
- A->getOption().matches(options::OPT_fPIE))
- CmdArgs.push_back("-pie");
- else
- CmdArgs.push_back("-no_pie");
- }
- Args.AddLastArg(CmdArgs, options::OPT_prebind);
- Args.AddLastArg(CmdArgs, options::OPT_noprebind);
- Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
- Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
- Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
- Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
- Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
- Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
- Args.AddAllArgs(CmdArgs, options::OPT_segprot);
- Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
- Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
- Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
- Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
- Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
- Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
- Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
- // Give --sysroot= preference, over the Apple specific behavior to also use
- // --isysroot as the syslibroot.
- StringRef sysroot = C.getSysRoot();
- if (sysroot != "") {
- CmdArgs.push_back("-syslibroot");
- CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
- } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
- CmdArgs.push_back("-syslibroot");
- CmdArgs.push_back(A->getValue());
- }
- Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
- Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
- Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
- Args.AddAllArgs(CmdArgs, options::OPT_undefined);
- Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
- Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
- Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
- Args.AddAllArgs(CmdArgs, options::OPT_y);
- Args.AddLastArg(CmdArgs, options::OPT_w);
- Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
- Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
- Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
- Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
- Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
- Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
- Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
- Args.AddLastArg(CmdArgs, options::OPT_whyload);
- Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
- Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
- Args.AddLastArg(CmdArgs, options::OPT_dylinker);
- Args.AddLastArg(CmdArgs, options::OPT_Mach);
- }
- void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
- // The logic here is derived from gcc's behavior; most of which
- // comes from specs (starting with link_command). Consult gcc for
- // more information.
- ArgStringList CmdArgs;
- /// Hack(tm) to ignore linking errors when we are doing ARC migration.
- if (Args.hasArg(options::OPT_ccc_arcmt_check,
- options::OPT_ccc_arcmt_migrate)) {
- for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
- (*I)->claim();
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("touch"));
- CmdArgs.push_back(Output.getFilename());
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- return;
- }
- // I'm not sure why this particular decomposition exists in gcc, but
- // we follow suite for ease of comparison.
- AddLinkArgs(C, Args, CmdArgs, Inputs);
- Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
- Args.AddAllArgs(CmdArgs, options::OPT_s);
- Args.AddAllArgs(CmdArgs, options::OPT_t);
- Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
- Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- Args.AddLastArg(CmdArgs, options::OPT_e);
- Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
- Args.AddAllArgs(CmdArgs, options::OPT_r);
- // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
- // members of static archive libraries which implement Objective-C classes or
- // categories.
- if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
- CmdArgs.push_back("-ObjC");
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export_dynamic");
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- // Derived from startfile spec.
- if (Args.hasArg(options::OPT_dynamiclib)) {
- // Derived from darwin_dylib1 spec.
- if (getDarwinToolChain().isTargetIOSSimulator()) {
- // The simulator doesn't have a versioned crt1 file.
- CmdArgs.push_back("-ldylib1.o");
- } else if (getDarwinToolChain().isTargetIPhoneOS()) {
- if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
- CmdArgs.push_back("-ldylib1.o");
- } else {
- if (getDarwinToolChain().isMacosxVersionLT(10, 5))
- CmdArgs.push_back("-ldylib1.o");
- else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
- CmdArgs.push_back("-ldylib1.10.5.o");
- }
- } else {
- if (Args.hasArg(options::OPT_bundle)) {
- if (!Args.hasArg(options::OPT_static)) {
- // Derived from darwin_bundle1 spec.
- if (getDarwinToolChain().isTargetIOSSimulator()) {
- // The simulator doesn't have a versioned crt1 file.
- CmdArgs.push_back("-lbundle1.o");
- } else if (getDarwinToolChain().isTargetIPhoneOS()) {
- if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
- CmdArgs.push_back("-lbundle1.o");
- } else {
- if (getDarwinToolChain().isMacosxVersionLT(10, 6))
- CmdArgs.push_back("-lbundle1.o");
- }
- }
- } else {
- if (Args.hasArg(options::OPT_pg) &&
- getToolChain().SupportsProfiling()) {
- if (Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_object) ||
- Args.hasArg(options::OPT_preload)) {
- CmdArgs.push_back("-lgcrt0.o");
- } else {
- CmdArgs.push_back("-lgcrt1.o");
- // darwin_crt2 spec is empty.
- }
- // By default on OS X 10.8 and later, we don't link with a crt1.o
- // file and the linker knows to use _main as the entry point. But,
- // when compiling with -pg, we need to link with the gcrt1.o file,
- // so pass the -no_new_main option to tell the linker to use the
- // "start" symbol as the entry point.
- if (getDarwinToolChain().isTargetMacOS() &&
- !getDarwinToolChain().isMacosxVersionLT(10, 8))
- CmdArgs.push_back("-no_new_main");
- } else {
- if (Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_object) ||
- Args.hasArg(options::OPT_preload)) {
- CmdArgs.push_back("-lcrt0.o");
- } else {
- // Derived from darwin_crt1 spec.
- if (getDarwinToolChain().isTargetIOSSimulator()) {
- // The simulator doesn't have a versioned crt1 file.
- CmdArgs.push_back("-lcrt1.o");
- } else if (getDarwinToolChain().isTargetIPhoneOS()) {
- if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
- CmdArgs.push_back("-lcrt1.o");
- else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
- CmdArgs.push_back("-lcrt1.3.1.o");
- } else {
- if (getDarwinToolChain().isMacosxVersionLT(10, 5))
- CmdArgs.push_back("-lcrt1.o");
- else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
- CmdArgs.push_back("-lcrt1.10.5.o");
- else if (getDarwinToolChain().isMacosxVersionLT(10, 8))
- CmdArgs.push_back("-lcrt1.10.6.o");
- // darwin_crt2 spec is empty.
- }
- }
- }
- }
- }
- if (!getDarwinToolChain().isTargetIPhoneOS() &&
- Args.hasArg(options::OPT_shared_libgcc) &&
- getDarwinToolChain().isMacosxVersionLT(10, 5)) {
- const char *Str =
- Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
- CmdArgs.push_back(Str);
- }
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- SanitizerArgs Sanitize(getToolChain().getDriver(), Args);
- // If we're building a dynamic lib with -fsanitize=address, or
- // -fsanitize=undefined, unresolved symbols may appear. Mark all
- // of them as dynamic_lookup. Linking executables is handled in
- // lib/Driver/ToolChains.cpp.
- if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) {
- if (Args.hasArg(options::OPT_dynamiclib) ||
- Args.hasArg(options::OPT_bundle)) {
- CmdArgs.push_back("-undefined");
- CmdArgs.push_back("dynamic_lookup");
- }
- }
- if (Args.hasArg(options::OPT_fopenmp))
- // This is more complicated in gcc...
- CmdArgs.push_back("-lgomp");
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
-
- if (isObjCRuntimeLinked(Args) &&
- !Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- // Avoid linking compatibility stubs on i386 mac.
- if (!getDarwinToolChain().isTargetMacOS() ||
- getDarwinToolChain().getArch() != llvm::Triple::x86) {
- // If we don't have ARC or subscripting runtime support, link in the
- // runtime stubs. We have to do this *before* adding any of the normal
- // linker inputs so that its initializer gets run first.
- ObjCRuntime runtime =
- getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
- // We use arclite library for both ARC and subscripting support.
- if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
- !runtime.hasSubscripting())
- getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
- }
- CmdArgs.push_back("-framework");
- CmdArgs.push_back("Foundation");
- // Link libobj.
- CmdArgs.push_back("-lobjc");
- }
- if (LinkingOutput) {
- CmdArgs.push_back("-arch_multiple");
- CmdArgs.push_back("-final_output");
- CmdArgs.push_back(LinkingOutput);
- }
- if (Args.hasArg(options::OPT_fnested_functions))
- CmdArgs.push_back("-allow_stack_execute");
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (getToolChain().getDriver().CCCIsCXX)
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- // link_ssp spec is empty.
- // Let the tool chain choose which runtime library to link.
- getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- // endfile_spec is empty.
- }
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_F);
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- CmdArgs.push_back("-create");
- assert(Output.isFilename() && "Unexpected lipo output.");
- CmdArgs.push_back("-output");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- assert(II.isFilename() && "Unexpected lipo input.");
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
- const InputInfo &Input = Inputs[0];
- assert(Input.isFilename() && "Unexpected dsymutil input.");
- CmdArgs.push_back(Input.getFilename());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- CmdArgs.push_back("--verify");
- CmdArgs.push_back("--debug-info");
- CmdArgs.push_back("--eh-frame");
- CmdArgs.push_back("--quiet");
- assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
- const InputInfo &Input = Inputs[0];
- assert(Input.isFilename() && "Unexpected verify input");
- // Grabbing the output of the earlier dsymutil run.
- CmdArgs.push_back(Input.getFilename());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- // FIXME: Find a real GCC, don't hard-code versions here
- std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/";
- const llvm::Triple &T = getToolChain().getTriple();
- std::string LibPath = "/usr/lib/";
- llvm::Triple::ArchType Arch = T.getArch();
- switch (Arch) {
- case llvm::Triple::x86:
- GCCLibPath += ("i386-" + T.getVendorName() + "-" +
- T.getOSName()).str() + "/4.5.2/";
- break;
- case llvm::Triple::x86_64:
- GCCLibPath += ("i386-" + T.getVendorName() + "-" +
- T.getOSName()).str();
- GCCLibPath += "/4.5.2/amd64/";
- LibPath += "amd64/";
- break;
- default:
- assert(0 && "Unsupported architecture");
- }
- ArgStringList CmdArgs;
- // Demangle C++ names in errors
- CmdArgs.push_back("-C");
- if ((!Args.hasArg(options::OPT_nostdlib)) &&
- (!Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("_start");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- CmdArgs.push_back("-dn");
- } else {
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- } else {
- CmdArgs.push_back("--dynamic-linker");
- CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
- }
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o"));
- CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
- CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
- CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
- } else {
- CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
- CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
- CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
- }
- if (getToolChain().getDriver().CCCIsCXX)
- CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
- }
- CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- Args.AddAllArgs(CmdArgs, options::OPT_r);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (getToolChain().getDriver().CCCIsCXX)
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lgcc_s");
- if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc");
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lm");
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
- }
- CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("gas"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- if ((!Args.hasArg(options::OPT_nostdlib)) &&
- (!Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("_start");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- CmdArgs.push_back("-dn");
- } else {
- // CmdArgs.push_back("--eh-frame-hdr");
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- } else {
- CmdArgs.push_back("--dynamic-linker");
- CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
- }
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crt1.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- }
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtn.o")));
- }
- CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
- + getToolChain().getTripleString()
- + "/4.2.4"));
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- // FIXME: For some reason GCC passes -lgcc before adding
- // the default system libraries. Just mimic this for now.
- CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-pthread");
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lgcc");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
- }
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- if ((!Args.hasArg(options::OPT_nostdlib)) &&
- (!Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("__start");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- } else {
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export-dynamic");
- CmdArgs.push_back("--eh-frame-hdr");
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- } else {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back("/usr/libexec/ld.so");
- }
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("gcrt0.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crt0.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbeginS.o")));
- }
- }
- std::string Triple = getToolChain().getTripleString();
- if (Triple.substr(0, 6) == "x86_64")
- Triple.replace(0, 6, "amd64");
- CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
- "/4.2.1"));
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lm_p");
- else
- CmdArgs.push_back("-lm");
- }
- // FIXME: For some reason GCC passes -lgcc before adding
- // the default system libraries. Just mimic this for now.
- CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_pthread)) {
- if (!Args.hasArg(options::OPT_shared) &&
- Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lpthread_p");
- else
- CmdArgs.push_back("-lpthread");
- }
- if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lc_p");
- else
- CmdArgs.push_back("-lc");
- }
- CmdArgs.push_back("-lgcc");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtendS.o")));
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- if ((!Args.hasArg(options::OPT_nostdlib)) &&
- (!Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-e");
- CmdArgs.push_back("__start");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- } else {
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export-dynamic");
- CmdArgs.push_back("--eh-frame-hdr");
- CmdArgs.push_back("-Bdynamic");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- } else {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back("/usr/libexec/ld.so");
- }
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("gcrt0.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crt0.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbeginS.o")));
- }
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lm_p");
- else
- CmdArgs.push_back("-lm");
- }
- if (Args.hasArg(options::OPT_pthread)) {
- if (!Args.hasArg(options::OPT_shared) &&
- Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lpthread_p");
- else
- CmdArgs.push_back("-lpthread");
- }
- if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lc_p");
- else
- CmdArgs.push_back("-lc");
- }
- std::string myarch = "-lclang_rt.";
- const llvm::Triple &T = getToolChain().getTriple();
- llvm::Triple::ArchType Arch = T.getArch();
- switch (Arch) {
- case llvm::Triple::arm:
- myarch += ("arm");
- break;
- case llvm::Triple::x86:
- myarch += ("i386");
- break;
- case llvm::Triple::x86_64:
- myarch += ("amd64");
- break;
- default:
- assert(0 && "Unsupported architecture");
- }
- CmdArgs.push_back(Args.MakeArgString(myarch));
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtendS.o")));
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- // When building 32-bit code on FreeBSD/amd64, we have to explicitly
- // instruct as in the base system to assemble 32-bit code.
- if (getToolChain().getArch() == llvm::Triple::x86)
- CmdArgs.push_back("--32");
- else if (getToolChain().getArch() == llvm::Triple::ppc)
- CmdArgs.push_back("-a32");
- else if (getToolChain().getArch() == llvm::Triple::mips ||
- getToolChain().getArch() == llvm::Triple::mipsel ||
- getToolChain().getArch() == llvm::Triple::mips64 ||
- getToolChain().getArch() == llvm::Triple::mips64el) {
- StringRef CPUName;
- StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
- CmdArgs.push_back("-march");
- CmdArgs.push_back(CPUName.data());
- // Convert ABI name to the GNU tools acceptable variant.
- if (ABIName == "o32")
- ABIName = "32";
- else if (ABIName == "n64")
- ABIName = "64";
- CmdArgs.push_back("-mabi");
- CmdArgs.push_back(ABIName.data());
- if (getToolChain().getArch() == llvm::Triple::mips ||
- getToolChain().getArch() == llvm::Triple::mips64)
- CmdArgs.push_back("-EB");
- else
- CmdArgs.push_back("-EL");
- Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
- options::OPT_fpic, options::OPT_fno_pic,
- options::OPT_fPIE, options::OPT_fno_PIE,
- options::OPT_fpie, options::OPT_fno_pie);
- if (LastPICArg &&
- (LastPICArg->getOption().matches(options::OPT_fPIC) ||
- LastPICArg->getOption().matches(options::OPT_fpic) ||
- LastPICArg->getOption().matches(options::OPT_fPIE) ||
- LastPICArg->getOption().matches(options::OPT_fpie))) {
- CmdArgs.push_back("-KPIC");
- }
- } else if (getToolChain().getArch() == llvm::Triple::arm ||
- getToolChain().getArch() == llvm::Triple::thumb) {
- CmdArgs.push_back("-mfpu=softvfp");
- switch(getToolChain().getTriple().getEnvironment()) {
- case llvm::Triple::GNUEABI:
- case llvm::Triple::EABI:
- break;
- default:
- CmdArgs.push_back("-matpcs");
- }
- }
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const toolchains::FreeBSD& ToolChain =
- static_cast<const toolchains::FreeBSD&>(getToolChain());
- const Driver &D = ToolChain.getDriver();
- ArgStringList CmdArgs;
- // Silence warning for "clang -g foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_g_Group);
- // and "clang -emit-llvm foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- // and for "clang -w foo.o -o foo". Other warning options are already
- // handled somewhere else.
- Args.ClaimAllArgs(options::OPT_w);
- if (!D.SysRoot.empty())
- CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_pie))
- CmdArgs.push_back("-pie");
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- } else {
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export-dynamic");
- CmdArgs.push_back("--eh-frame-hdr");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-Bshareable");
- } else {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back("/libexec/ld-elf.so.1");
- }
- if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
- llvm::Triple::ArchType Arch = ToolChain.getArch();
- if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
- Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
- CmdArgs.push_back("--hash-style=both");
- }
- }
- CmdArgs.push_back("--enable-new-dtags");
- }
- // When building 32-bit code on FreeBSD/amd64, we have to explicitly
- // instruct ld in the base system to link 32-bit code.
- if (ToolChain.getArch() == llvm::Triple::x86) {
- CmdArgs.push_back("-m");
- CmdArgs.push_back("elf_i386_fbsd");
- }
- if (ToolChain.getArch() == llvm::Triple::ppc) {
- CmdArgs.push_back("-m");
- CmdArgs.push_back("elf32ppc_fbsd");
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- const char *crt1 = NULL;
- if (!Args.hasArg(options::OPT_shared)) {
- if (Args.hasArg(options::OPT_pg))
- crt1 = "gcrt1.o";
- else if (Args.hasArg(options::OPT_pie))
- crt1 = "Scrt1.o";
- else
- crt1 = "crt1.o";
- }
- if (crt1)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
- const char *crtbegin = NULL;
- if (Args.hasArg(options::OPT_static))
- crtbegin = "crtbeginT.o";
- else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
- crtbegin = "crtbeginS.o";
- else
- crtbegin = "crtbegin.o";
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- const ToolChain::path_list Paths = ToolChain.getFilePaths();
- for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
- i != e; ++i)
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- Args.AddAllArgs(CmdArgs, options::OPT_s);
- Args.AddAllArgs(CmdArgs, options::OPT_t);
- Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
- Args.AddAllArgs(CmdArgs, options::OPT_r);
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
- ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lm_p");
- else
- CmdArgs.push_back("-lm");
- }
- // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
- // the default system libraries. Just mimic this for now.
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lgcc_p");
- else
- CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-lgcc_eh");
- } else if (Args.hasArg(options::OPT_pg)) {
- CmdArgs.push_back("-lgcc_eh_p");
- } else {
- CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("--no-as-needed");
- }
- if (Args.hasArg(options::OPT_pthread)) {
- if (Args.hasArg(options::OPT_pg))
- CmdArgs.push_back("-lpthread_p");
- else
- CmdArgs.push_back("-lpthread");
- }
- if (Args.hasArg(options::OPT_pg)) {
- if (Args.hasArg(options::OPT_shared))
- CmdArgs.push_back("-lc");
- else
- CmdArgs.push_back("-lc_p");
- CmdArgs.push_back("-lgcc_p");
- } else {
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lgcc");
- }
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-lgcc_eh");
- } else if (Args.hasArg(options::OPT_pg)) {
- CmdArgs.push_back("-lgcc_eh_p");
- } else {
- CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("--no-as-needed");
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
- }
- addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
- const char *Exec =
- Args.MakeArgString(ToolChain.GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- // When building 32-bit code on NetBSD/amd64, we have to explicitly
- // instruct as in the base system to assemble 32-bit code.
- if (getToolChain().getArch() == llvm::Triple::x86)
- CmdArgs.push_back("--32");
- // Set byte order explicitly
- if (getToolChain().getArch() == llvm::Triple::mips)
- CmdArgs.push_back("-EB");
- else if (getToolChain().getArch() == llvm::Triple::mipsel)
- CmdArgs.push_back("-EL");
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- if (!D.SysRoot.empty())
- CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- } else {
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export-dynamic");
- CmdArgs.push_back("--eh-frame-hdr");
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-Bshareable");
- } else {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back("/libexec/ld.elf_so");
- }
- }
- // When building 32-bit code on NetBSD/amd64, we have to explicitly
- // instruct ld in the base system to link 32-bit code.
- if (getToolChain().getArch() == llvm::Triple::x86) {
- CmdArgs.push_back("-m");
- CmdArgs.push_back("elf_i386");
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crt0.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtbeginS.o")));
- }
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- Args.AddAllArgs(CmdArgs, options::OPT_s);
- Args.AddAllArgs(CmdArgs, options::OPT_t);
- Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
- Args.AddAllArgs(CmdArgs, options::OPT_r);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lm");
- }
- // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
- // the default system libraries. Just mimic this for now.
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-lgcc_eh");
- } else {
- CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("--no-as-needed");
- }
- CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lgcc");
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-lgcc_eh");
- } else {
- CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
- CmdArgs.push_back("--no-as-needed");
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtend.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtendS.o")));
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
- "crtn.o")));
- }
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- // Add --32/--64 to make sure we get the format we want.
- // This is incomplete
- if (getToolChain().getArch() == llvm::Triple::x86) {
- CmdArgs.push_back("--32");
- } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
- CmdArgs.push_back("--64");
- } else if (getToolChain().getArch() == llvm::Triple::ppc) {
- CmdArgs.push_back("-a32");
- CmdArgs.push_back("-mppc");
- CmdArgs.push_back("-many");
- } else if (getToolChain().getArch() == llvm::Triple::ppc64) {
- CmdArgs.push_back("-a64");
- CmdArgs.push_back("-mppc64");
- CmdArgs.push_back("-many");
- } else if (getToolChain().getArch() == llvm::Triple::arm) {
- StringRef MArch = getToolChain().getArchName();
- if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
- CmdArgs.push_back("-mfpu=neon");
- StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
- getToolChain().getTriple());
- CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
- Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
- Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
- Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
- } else if (getToolChain().getArch() == llvm::Triple::mips ||
- getToolChain().getArch() == llvm::Triple::mipsel ||
- getToolChain().getArch() == llvm::Triple::mips64 ||
- getToolChain().getArch() == llvm::Triple::mips64el) {
- StringRef CPUName;
- StringRef ABIName;
- getMipsCPUAndABI(Args, getToolChain(), CPUName, ABIName);
- CmdArgs.push_back("-march");
- CmdArgs.push_back(CPUName.data());
- // Convert ABI name to the GNU tools acceptable variant.
- if (ABIName == "o32")
- ABIName = "32";
- else if (ABIName == "n64")
- ABIName = "64";
- CmdArgs.push_back("-mabi");
- CmdArgs.push_back(ABIName.data());
- if (getToolChain().getArch() == llvm::Triple::mips ||
- getToolChain().getArch() == llvm::Triple::mips64)
- CmdArgs.push_back("-EB");
- else
- CmdArgs.push_back("-EL");
- Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
- options::OPT_fpic, options::OPT_fno_pic,
- options::OPT_fPIE, options::OPT_fno_PIE,
- options::OPT_fpie, options::OPT_fno_pie);
- if (LastPICArg &&
- (LastPICArg->getOption().matches(options::OPT_fPIC) ||
- LastPICArg->getOption().matches(options::OPT_fpic) ||
- LastPICArg->getOption().matches(options::OPT_fPIE) ||
- LastPICArg->getOption().matches(options::OPT_fpie))) {
- CmdArgs.push_back("-KPIC");
- }
- }
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- static void AddLibgcc(llvm::Triple Triple, const Driver &D,
- ArgStringList &CmdArgs, const ArgList &Args) {
- bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
- bool StaticLibgcc = Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_static_libgcc);
- if (!D.CCCIsCXX)
- CmdArgs.push_back("-lgcc");
- if (StaticLibgcc || isAndroid) {
- if (D.CCCIsCXX)
- CmdArgs.push_back("-lgcc");
- } else {
- if (!D.CCCIsCXX)
- CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
- if (!D.CCCIsCXX)
- CmdArgs.push_back("--no-as-needed");
- }
- if (StaticLibgcc && !isAndroid)
- CmdArgs.push_back("-lgcc_eh");
- else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX)
- CmdArgs.push_back("-lgcc");
- // According to Android ABI, we have to link with libdl if we are
- // linking with non-static libgcc.
- //
- // NOTE: This fixes a link error on Android MIPS as well. The non-static
- // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
- if (isAndroid && !StaticLibgcc)
- CmdArgs.push_back("-ldl");
- }
- static bool hasMipsN32ABIArg(const ArgList &Args) {
- Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
- return A && (A->getValue() == StringRef("n32"));
- }
- void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const toolchains::Linux& ToolChain =
- static_cast<const toolchains::Linux&>(getToolChain());
- const Driver &D = ToolChain.getDriver();
- const bool isAndroid =
- ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
- ArgStringList CmdArgs;
- // Silence warning for "clang -g foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_g_Group);
- // and "clang -emit-llvm foo.o -o foo"
- Args.ClaimAllArgs(options::OPT_emit_llvm);
- // and for "clang -w foo.o -o foo". Other warning options are already
- // handled somewhere else.
- Args.ClaimAllArgs(options::OPT_w);
- if (!D.SysRoot.empty())
- CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_pie))
- CmdArgs.push_back("-pie");
- if (Args.hasArg(options::OPT_rdynamic))
- CmdArgs.push_back("-export-dynamic");
- if (Args.hasArg(options::OPT_s))
- CmdArgs.push_back("-s");
- for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
- e = ToolChain.ExtraOpts.end();
- i != e; ++i)
- CmdArgs.push_back(i->c_str());
- if (!Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("--eh-frame-hdr");
- }
- CmdArgs.push_back("-m");
- if (ToolChain.getArch() == llvm::Triple::x86)
- CmdArgs.push_back("elf_i386");
- else if (ToolChain.getArch() == llvm::Triple::arm
- || ToolChain.getArch() == llvm::Triple::thumb)
- CmdArgs.push_back("armelf_linux_eabi");
- else if (ToolChain.getArch() == llvm::Triple::ppc)
- CmdArgs.push_back("elf32ppclinux");
- else if (ToolChain.getArch() == llvm::Triple::ppc64)
- CmdArgs.push_back("elf64ppc");
- else if (ToolChain.getArch() == llvm::Triple::mips)
- CmdArgs.push_back("elf32btsmip");
- else if (ToolChain.getArch() == llvm::Triple::mipsel)
- CmdArgs.push_back("elf32ltsmip");
- else if (ToolChain.getArch() == llvm::Triple::mips64) {
- if (hasMipsN32ABIArg(Args))
- CmdArgs.push_back("elf32btsmipn32");
- else
- CmdArgs.push_back("elf64btsmip");
- }
- else if (ToolChain.getArch() == llvm::Triple::mips64el) {
- if (hasMipsN32ABIArg(Args))
- CmdArgs.push_back("elf32ltsmipn32");
- else
- CmdArgs.push_back("elf64ltsmip");
- }
- else
- CmdArgs.push_back("elf_x86_64");
- if (Args.hasArg(options::OPT_static)) {
- if (ToolChain.getArch() == llvm::Triple::arm
- || ToolChain.getArch() == llvm::Triple::thumb)
- CmdArgs.push_back("-Bstatic");
- else
- CmdArgs.push_back("-static");
- } else if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-shared");
- if (isAndroid) {
- CmdArgs.push_back("-Bsymbolic");
- }
- }
- if (ToolChain.getArch() == llvm::Triple::arm ||
- ToolChain.getArch() == llvm::Triple::thumb ||
- (!Args.hasArg(options::OPT_static) &&
- !Args.hasArg(options::OPT_shared))) {
- CmdArgs.push_back("-dynamic-linker");
- if (isAndroid)
- CmdArgs.push_back("/system/bin/linker");
- else if (ToolChain.getArch() == llvm::Triple::x86)
- CmdArgs.push_back("/lib/ld-linux.so.2");
- else if (ToolChain.getArch() == llvm::Triple::arm ||
- ToolChain.getArch() == llvm::Triple::thumb) {
- if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
- CmdArgs.push_back("/lib/ld-linux-armhf.so.3");
- else
- CmdArgs.push_back("/lib/ld-linux.so.3");
- }
- else if (ToolChain.getArch() == llvm::Triple::mips ||
- ToolChain.getArch() == llvm::Triple::mipsel)
- CmdArgs.push_back("/lib/ld.so.1");
- else if (ToolChain.getArch() == llvm::Triple::mips64 ||
- ToolChain.getArch() == llvm::Triple::mips64el) {
- if (hasMipsN32ABIArg(Args))
- CmdArgs.push_back("/lib32/ld.so.1");
- else
- CmdArgs.push_back("/lib64/ld.so.1");
- }
- else if (ToolChain.getArch() == llvm::Triple::ppc)
- CmdArgs.push_back("/lib/ld.so.1");
- else if (ToolChain.getArch() == llvm::Triple::ppc64)
- CmdArgs.push_back("/lib64/ld64.so.1");
- else
- CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2");
- }
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!isAndroid) {
- const char *crt1 = NULL;
- if (!Args.hasArg(options::OPT_shared)){
- if (Args.hasArg(options::OPT_pie))
- crt1 = "Scrt1.o";
- else
- crt1 = "crt1.o";
- }
- if (crt1)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
- }
- const char *crtbegin;
- if (Args.hasArg(options::OPT_static))
- crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
- else if (Args.hasArg(options::OPT_shared))
- crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
- else if (Args.hasArg(options::OPT_pie))
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
- else
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
- // Add crtfastmath.o if available and fast math is enabled.
- ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- const ToolChain::path_list Paths = ToolChain.getFilePaths();
- for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
- i != e; ++i)
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
- // Tell the linker to load the plugin. This has to come before AddLinkerInputs
- // as gold requires -plugin to come before any -plugin-opt that -Wl might
- // forward.
- if (D.IsUsingLTO(Args) || Args.hasArg(options::OPT_use_gold_plugin)) {
- CmdArgs.push_back("-plugin");
- std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
- CmdArgs.push_back(Args.MakeArgString(Plugin));
- }
- if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
- CmdArgs.push_back("--no-demangle");
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- SanitizerArgs Sanitize(D, Args);
- // Call these before we add the C++ ABI library.
- if (Sanitize.needsUbsanRt())
- addUbsanRTLinux(getToolChain(), Args, CmdArgs);
- if (Sanitize.needsAsanRt())
- addAsanRTLinux(getToolChain(), Args, CmdArgs);
- if (Sanitize.needsTsanRt())
- addTsanRTLinux(getToolChain(), Args, CmdArgs);
- if (Sanitize.needsMsanRt())
- addMsanRTLinux(getToolChain(), Args, CmdArgs);
- if (D.CCCIsCXX &&
- !Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
- !Args.hasArg(options::OPT_static);
- if (OnlyLibstdcxxStatic)
- CmdArgs.push_back("-Bstatic");
- ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
- if (OnlyLibstdcxxStatic)
- CmdArgs.push_back("-Bdynamic");
- CmdArgs.push_back("-lm");
- }
- if (!Args.hasArg(options::OPT_nostdlib)) {
- if (!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("--start-group");
- AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
- if (Args.hasArg(options::OPT_pthread) ||
- Args.hasArg(options::OPT_pthreads))
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-lc");
- if (Args.hasArg(options::OPT_static))
- CmdArgs.push_back("--end-group");
- else
- AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
- }
- if (!Args.hasArg(options::OPT_nostartfiles)) {
- const char *crtend;
- if (Args.hasArg(options::OPT_shared))
- crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
- else if (Args.hasArg(options::OPT_pie))
- crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
- else
- crtend = isAndroid ? "crtend_android.o" : "crtend.o";
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
- if (!isAndroid)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
- }
- }
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
- }
- void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
- CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lm");
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
- CmdArgs.push_back("-lc");
- CmdArgs.push_back("-lCompilerRT-Generic");
- CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
- }
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- /// DragonFly Tools
- // For now, DragonFly Assemble does just about the same as for
- // FreeBSD, but this may change soon.
- void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- // When building 32-bit code on DragonFly/pc64, we have to explicitly
- // instruct as in the base system to assemble 32-bit code.
- if (getToolChain().getArch() == llvm::Triple::x86)
- CmdArgs.push_back("--32");
- Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
- options::OPT_Xassembler);
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
- CmdArgs.push_back(II.getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("as"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
- ArgStringList CmdArgs;
- if (!D.SysRoot.empty())
- CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
- if (Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-Bstatic");
- } else {
- if (Args.hasArg(options::OPT_shared))
- CmdArgs.push_back("-Bshareable");
- else {
- CmdArgs.push_back("-dynamic-linker");
- CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
- }
- }
- // When building 32-bit code on DragonFly/pc64, we have to explicitly
- // instruct ld in the base system to link 32-bit code.
- if (getToolChain().getArch() == llvm::Triple::x86) {
- CmdArgs.push_back("-m");
- CmdArgs.push_back("elf_i386");
- }
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
- } else {
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
- CmdArgs.push_back(
- Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
- }
- }
- Args.AddAllArgs(CmdArgs, options::OPT_L);
- Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
- Args.AddAllArgs(CmdArgs, options::OPT_e);
- AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nodefaultlibs)) {
- // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
- // rpaths
- CmdArgs.push_back("-L/usr/lib/gcc41");
- if (!Args.hasArg(options::OPT_static)) {
- CmdArgs.push_back("-rpath");
- CmdArgs.push_back("/usr/lib/gcc41");
- CmdArgs.push_back("-rpath-link");
- CmdArgs.push_back("/usr/lib/gcc41");
- CmdArgs.push_back("-rpath");
- CmdArgs.push_back("/usr/lib");
- CmdArgs.push_back("-rpath-link");
- CmdArgs.push_back("/usr/lib");
- }
- if (D.CCCIsCXX) {
- getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
- CmdArgs.push_back("-lm");
- }
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc_pic");
- } else {
- CmdArgs.push_back("-lgcc");
- }
- if (Args.hasArg(options::OPT_pthread))
- CmdArgs.push_back("-lpthread");
- if (!Args.hasArg(options::OPT_nolibc)) {
- CmdArgs.push_back("-lc");
- }
- if (Args.hasArg(options::OPT_shared)) {
- CmdArgs.push_back("-lgcc_pic");
- } else {
- CmdArgs.push_back("-lgcc");
- }
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- if (!Args.hasArg(options::OPT_shared))
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtend.o")));
- else
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtendS.o")));
- CmdArgs.push_back(Args.MakeArgString(
- getToolChain().GetFilePath("crtn.o")));
- }
- addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("ld"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
- void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- ArgStringList CmdArgs;
- if (Output.isFilename()) {
- CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
- Output.getFilename()));
- } else {
- assert(Output.isNothing() && "Invalid output.");
- }
- if (!Args.hasArg(options::OPT_nostdlib) &&
- !Args.hasArg(options::OPT_nostartfiles)) {
- CmdArgs.push_back("-defaultlib:libcmt");
- }
- CmdArgs.push_back("-nologo");
- Args.AddAllArgValues(CmdArgs, options::OPT_l);
- // Add filenames immediately.
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- if (it->isFilename())
- CmdArgs.push_back(it->getFilename());
- }
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
- }
|