ParsePragma.cpp 130 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800
  1. //===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the language specific #pragma handlers.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/ASTContext.h"
  13. #include "clang/Basic/PragmaKinds.h"
  14. #include "clang/Basic/TargetInfo.h"
  15. #include "clang/Lex/Preprocessor.h"
  16. #include "clang/Lex/Token.h"
  17. #include "clang/Parse/LoopHint.h"
  18. #include "clang/Parse/ParseDiagnostic.h"
  19. #include "clang/Parse/Parser.h"
  20. #include "clang/Parse/RAIIObjectsForParser.h"
  21. #include "clang/Sema/Scope.h"
  22. #include "llvm/ADT/ArrayRef.h"
  23. #include "llvm/ADT/StringSwitch.h"
  24. using namespace clang;
  25. namespace {
  26. struct PragmaAlignHandler : public PragmaHandler {
  27. explicit PragmaAlignHandler() : PragmaHandler("align") {}
  28. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  29. Token &FirstToken) override;
  30. };
  31. struct PragmaGCCVisibilityHandler : public PragmaHandler {
  32. explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
  33. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  34. Token &FirstToken) override;
  35. };
  36. struct PragmaOptionsHandler : public PragmaHandler {
  37. explicit PragmaOptionsHandler() : PragmaHandler("options") {}
  38. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  39. Token &FirstToken) override;
  40. };
  41. struct PragmaPackHandler : public PragmaHandler {
  42. explicit PragmaPackHandler() : PragmaHandler("pack") {}
  43. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  44. Token &FirstToken) override;
  45. };
  46. struct PragmaClangSectionHandler : public PragmaHandler {
  47. explicit PragmaClangSectionHandler(Sema &S)
  48. : PragmaHandler("section"), Actions(S) {}
  49. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  50. Token &FirstToken) override;
  51. private:
  52. Sema &Actions;
  53. };
  54. struct PragmaMSStructHandler : public PragmaHandler {
  55. explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
  56. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  57. Token &FirstToken) override;
  58. };
  59. struct PragmaUnusedHandler : public PragmaHandler {
  60. PragmaUnusedHandler() : PragmaHandler("unused") {}
  61. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  62. Token &FirstToken) override;
  63. };
  64. struct PragmaWeakHandler : public PragmaHandler {
  65. explicit PragmaWeakHandler() : PragmaHandler("weak") {}
  66. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  67. Token &FirstToken) override;
  68. };
  69. struct PragmaRedefineExtnameHandler : public PragmaHandler {
  70. explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
  71. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  72. Token &FirstToken) override;
  73. };
  74. struct PragmaOpenCLExtensionHandler : public PragmaHandler {
  75. PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
  76. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  77. Token &FirstToken) override;
  78. };
  79. struct PragmaFPContractHandler : public PragmaHandler {
  80. PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
  81. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  82. Token &FirstToken) override;
  83. };
  84. // Pragma STDC implementations.
  85. /// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
  86. struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
  87. PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
  88. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  89. Token &Tok) override {
  90. Token PragmaName = Tok;
  91. if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) {
  92. PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
  93. << PragmaName.getIdentifierInfo()->getName();
  94. return;
  95. }
  96. tok::OnOffSwitch OOS;
  97. if (PP.LexOnOffSwitch(OOS))
  98. return;
  99. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  100. 1);
  101. Toks[0].startToken();
  102. Toks[0].setKind(tok::annot_pragma_fenv_access);
  103. Toks[0].setLocation(Tok.getLocation());
  104. Toks[0].setAnnotationEndLoc(Tok.getLocation());
  105. Toks[0].setAnnotationValue(reinterpret_cast<void*>(
  106. static_cast<uintptr_t>(OOS)));
  107. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  108. /*IsReinject=*/false);
  109. }
  110. };
  111. /// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
  112. struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
  113. PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
  114. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  115. Token &Tok) override {
  116. tok::OnOffSwitch OOS;
  117. PP.LexOnOffSwitch(OOS);
  118. }
  119. };
  120. /// Handler for "\#pragma STDC FENV_ROUND ...".
  121. struct PragmaSTDC_FENV_ROUNDHandler : public PragmaHandler {
  122. PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler("FENV_ROUND") {}
  123. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  124. Token &Tok) override;
  125. };
  126. /// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
  127. struct PragmaSTDC_UnknownHandler : public PragmaHandler {
  128. PragmaSTDC_UnknownHandler() = default;
  129. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  130. Token &UnknownTok) override {
  131. // C99 6.10.6p2, unknown forms are not allowed.
  132. PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
  133. }
  134. };
  135. struct PragmaFPHandler : public PragmaHandler {
  136. PragmaFPHandler() : PragmaHandler("fp") {}
  137. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  138. Token &FirstToken) override;
  139. };
  140. struct PragmaNoOpenMPHandler : public PragmaHandler {
  141. PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
  142. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  143. Token &FirstToken) override;
  144. };
  145. struct PragmaOpenMPHandler : public PragmaHandler {
  146. PragmaOpenMPHandler() : PragmaHandler("omp") { }
  147. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  148. Token &FirstToken) override;
  149. };
  150. /// PragmaCommentHandler - "\#pragma comment ...".
  151. struct PragmaCommentHandler : public PragmaHandler {
  152. PragmaCommentHandler(Sema &Actions)
  153. : PragmaHandler("comment"), Actions(Actions) {}
  154. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  155. Token &FirstToken) override;
  156. private:
  157. Sema &Actions;
  158. };
  159. struct PragmaDetectMismatchHandler : public PragmaHandler {
  160. PragmaDetectMismatchHandler(Sema &Actions)
  161. : PragmaHandler("detect_mismatch"), Actions(Actions) {}
  162. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  163. Token &FirstToken) override;
  164. private:
  165. Sema &Actions;
  166. };
  167. struct PragmaFloatControlHandler : public PragmaHandler {
  168. PragmaFloatControlHandler(Sema &Actions)
  169. : PragmaHandler("float_control") {}
  170. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  171. Token &FirstToken) override;
  172. };
  173. struct PragmaMSPointersToMembers : public PragmaHandler {
  174. explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
  175. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  176. Token &FirstToken) override;
  177. };
  178. struct PragmaMSVtorDisp : public PragmaHandler {
  179. explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
  180. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  181. Token &FirstToken) override;
  182. };
  183. struct PragmaMSPragma : public PragmaHandler {
  184. explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
  185. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  186. Token &FirstToken) override;
  187. };
  188. /// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
  189. struct PragmaOptimizeHandler : public PragmaHandler {
  190. PragmaOptimizeHandler(Sema &S)
  191. : PragmaHandler("optimize"), Actions(S) {}
  192. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  193. Token &FirstToken) override;
  194. private:
  195. Sema &Actions;
  196. };
  197. struct PragmaLoopHintHandler : public PragmaHandler {
  198. PragmaLoopHintHandler() : PragmaHandler("loop") {}
  199. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  200. Token &FirstToken) override;
  201. };
  202. struct PragmaUnrollHintHandler : public PragmaHandler {
  203. PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
  204. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  205. Token &FirstToken) override;
  206. };
  207. struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
  208. PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
  209. };
  210. struct PragmaMSIntrinsicHandler : public PragmaHandler {
  211. PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
  212. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  213. Token &FirstToken) override;
  214. };
  215. struct PragmaMSOptimizeHandler : public PragmaHandler {
  216. PragmaMSOptimizeHandler() : PragmaHandler("optimize") {}
  217. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  218. Token &FirstToken) override;
  219. };
  220. // "\#pragma fenv_access (on)".
  221. struct PragmaMSFenvAccessHandler : public PragmaHandler {
  222. PragmaMSFenvAccessHandler() : PragmaHandler("fenv_access") {}
  223. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  224. Token &FirstToken) override {
  225. StringRef PragmaName = FirstToken.getIdentifierInfo()->getName();
  226. if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) {
  227. PP.Diag(FirstToken.getLocation(), diag::warn_pragma_fp_ignored)
  228. << PragmaName;
  229. return;
  230. }
  231. Token Tok;
  232. PP.Lex(Tok);
  233. if (Tok.isNot(tok::l_paren)) {
  234. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
  235. << PragmaName;
  236. return;
  237. }
  238. PP.Lex(Tok); // Consume the l_paren.
  239. if (Tok.isNot(tok::identifier)) {
  240. PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
  241. return;
  242. }
  243. const IdentifierInfo *II = Tok.getIdentifierInfo();
  244. tok::OnOffSwitch OOS;
  245. if (II->isStr("on")) {
  246. OOS = tok::OOS_ON;
  247. PP.Lex(Tok);
  248. } else if (II->isStr("off")) {
  249. OOS = tok::OOS_OFF;
  250. PP.Lex(Tok);
  251. } else {
  252. PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
  253. return;
  254. }
  255. if (Tok.isNot(tok::r_paren)) {
  256. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
  257. << PragmaName;
  258. return;
  259. }
  260. PP.Lex(Tok); // Consume the r_paren.
  261. if (Tok.isNot(tok::eod)) {
  262. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  263. << PragmaName;
  264. return;
  265. }
  266. MutableArrayRef<Token> Toks(
  267. PP.getPreprocessorAllocator().Allocate<Token>(1), 1);
  268. Toks[0].startToken();
  269. Toks[0].setKind(tok::annot_pragma_fenv_access_ms);
  270. Toks[0].setLocation(FirstToken.getLocation());
  271. Toks[0].setAnnotationEndLoc(Tok.getLocation());
  272. Toks[0].setAnnotationValue(
  273. reinterpret_cast<void*>(static_cast<uintptr_t>(OOS)));
  274. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  275. /*IsReinject=*/false);
  276. }
  277. };
  278. struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
  279. PragmaForceCUDAHostDeviceHandler(Sema &Actions)
  280. : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
  281. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  282. Token &FirstToken) override;
  283. private:
  284. Sema &Actions;
  285. };
  286. /// PragmaAttributeHandler - "\#pragma clang attribute ...".
  287. struct PragmaAttributeHandler : public PragmaHandler {
  288. PragmaAttributeHandler(AttributeFactory &AttrFactory)
  289. : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
  290. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  291. Token &FirstToken) override;
  292. /// A pool of attributes that were parsed in \#pragma clang attribute.
  293. ParsedAttributes AttributesForPragmaAttribute;
  294. };
  295. struct PragmaMaxTokensHereHandler : public PragmaHandler {
  296. PragmaMaxTokensHereHandler() : PragmaHandler("max_tokens_here") {}
  297. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  298. Token &FirstToken) override;
  299. };
  300. struct PragmaMaxTokensTotalHandler : public PragmaHandler {
  301. PragmaMaxTokensTotalHandler() : PragmaHandler("max_tokens_total") {}
  302. void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
  303. Token &FirstToken) override;
  304. };
  305. void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) {
  306. for (auto &T : Toks)
  307. T.setFlag(clang::Token::IsReinjected);
  308. }
  309. } // end namespace
  310. void Parser::initializePragmaHandlers() {
  311. AlignHandler = std::make_unique<PragmaAlignHandler>();
  312. PP.AddPragmaHandler(AlignHandler.get());
  313. GCCVisibilityHandler = std::make_unique<PragmaGCCVisibilityHandler>();
  314. PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
  315. OptionsHandler = std::make_unique<PragmaOptionsHandler>();
  316. PP.AddPragmaHandler(OptionsHandler.get());
  317. PackHandler = std::make_unique<PragmaPackHandler>();
  318. PP.AddPragmaHandler(PackHandler.get());
  319. MSStructHandler = std::make_unique<PragmaMSStructHandler>();
  320. PP.AddPragmaHandler(MSStructHandler.get());
  321. UnusedHandler = std::make_unique<PragmaUnusedHandler>();
  322. PP.AddPragmaHandler(UnusedHandler.get());
  323. WeakHandler = std::make_unique<PragmaWeakHandler>();
  324. PP.AddPragmaHandler(WeakHandler.get());
  325. RedefineExtnameHandler = std::make_unique<PragmaRedefineExtnameHandler>();
  326. PP.AddPragmaHandler(RedefineExtnameHandler.get());
  327. FPContractHandler = std::make_unique<PragmaFPContractHandler>();
  328. PP.AddPragmaHandler("STDC", FPContractHandler.get());
  329. STDCFenvAccessHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
  330. PP.AddPragmaHandler("STDC", STDCFenvAccessHandler.get());
  331. STDCFenvRoundHandler = std::make_unique<PragmaSTDC_FENV_ROUNDHandler>();
  332. PP.AddPragmaHandler("STDC", STDCFenvRoundHandler.get());
  333. STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
  334. PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get());
  335. STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
  336. PP.AddPragmaHandler("STDC", STDCUnknownHandler.get());
  337. PCSectionHandler = std::make_unique<PragmaClangSectionHandler>(Actions);
  338. PP.AddPragmaHandler("clang", PCSectionHandler.get());
  339. if (getLangOpts().OpenCL) {
  340. OpenCLExtensionHandler = std::make_unique<PragmaOpenCLExtensionHandler>();
  341. PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
  342. PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
  343. }
  344. if (getLangOpts().OpenMP)
  345. OpenMPHandler = std::make_unique<PragmaOpenMPHandler>();
  346. else
  347. OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
  348. PP.AddPragmaHandler(OpenMPHandler.get());
  349. if (getLangOpts().MicrosoftExt ||
  350. getTargetInfo().getTriple().isOSBinFormatELF()) {
  351. MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
  352. PP.AddPragmaHandler(MSCommentHandler.get());
  353. }
  354. FloatControlHandler = std::make_unique<PragmaFloatControlHandler>(Actions);
  355. PP.AddPragmaHandler(FloatControlHandler.get());
  356. if (getLangOpts().MicrosoftExt) {
  357. MSDetectMismatchHandler =
  358. std::make_unique<PragmaDetectMismatchHandler>(Actions);
  359. PP.AddPragmaHandler(MSDetectMismatchHandler.get());
  360. MSPointersToMembers = std::make_unique<PragmaMSPointersToMembers>();
  361. PP.AddPragmaHandler(MSPointersToMembers.get());
  362. MSVtorDisp = std::make_unique<PragmaMSVtorDisp>();
  363. PP.AddPragmaHandler(MSVtorDisp.get());
  364. MSInitSeg = std::make_unique<PragmaMSPragma>("init_seg");
  365. PP.AddPragmaHandler(MSInitSeg.get());
  366. MSDataSeg = std::make_unique<PragmaMSPragma>("data_seg");
  367. PP.AddPragmaHandler(MSDataSeg.get());
  368. MSBSSSeg = std::make_unique<PragmaMSPragma>("bss_seg");
  369. PP.AddPragmaHandler(MSBSSSeg.get());
  370. MSConstSeg = std::make_unique<PragmaMSPragma>("const_seg");
  371. PP.AddPragmaHandler(MSConstSeg.get());
  372. MSCodeSeg = std::make_unique<PragmaMSPragma>("code_seg");
  373. PP.AddPragmaHandler(MSCodeSeg.get());
  374. MSSection = std::make_unique<PragmaMSPragma>("section");
  375. PP.AddPragmaHandler(MSSection.get());
  376. MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
  377. PP.AddPragmaHandler(MSRuntimeChecks.get());
  378. MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
  379. PP.AddPragmaHandler(MSIntrinsic.get());
  380. MSOptimize = std::make_unique<PragmaMSOptimizeHandler>();
  381. PP.AddPragmaHandler(MSOptimize.get());
  382. MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
  383. PP.AddPragmaHandler(MSFenvAccess.get());
  384. }
  385. if (getLangOpts().CUDA) {
  386. CUDAForceHostDeviceHandler =
  387. std::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
  388. PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
  389. }
  390. OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
  391. PP.AddPragmaHandler("clang", OptimizeHandler.get());
  392. LoopHintHandler = std::make_unique<PragmaLoopHintHandler>();
  393. PP.AddPragmaHandler("clang", LoopHintHandler.get());
  394. UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("unroll");
  395. PP.AddPragmaHandler(UnrollHintHandler.get());
  396. PP.AddPragmaHandler("GCC", UnrollHintHandler.get());
  397. NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>("nounroll");
  398. PP.AddPragmaHandler(NoUnrollHintHandler.get());
  399. PP.AddPragmaHandler("GCC", NoUnrollHintHandler.get());
  400. UnrollAndJamHintHandler =
  401. std::make_unique<PragmaUnrollHintHandler>("unroll_and_jam");
  402. PP.AddPragmaHandler(UnrollAndJamHintHandler.get());
  403. NoUnrollAndJamHintHandler =
  404. std::make_unique<PragmaUnrollHintHandler>("nounroll_and_jam");
  405. PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
  406. FPHandler = std::make_unique<PragmaFPHandler>();
  407. PP.AddPragmaHandler("clang", FPHandler.get());
  408. AttributePragmaHandler =
  409. std::make_unique<PragmaAttributeHandler>(AttrFactory);
  410. PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
  411. MaxTokensHerePragmaHandler = std::make_unique<PragmaMaxTokensHereHandler>();
  412. PP.AddPragmaHandler("clang", MaxTokensHerePragmaHandler.get());
  413. MaxTokensTotalPragmaHandler = std::make_unique<PragmaMaxTokensTotalHandler>();
  414. PP.AddPragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
  415. }
  416. void Parser::resetPragmaHandlers() {
  417. // Remove the pragma handlers we installed.
  418. PP.RemovePragmaHandler(AlignHandler.get());
  419. AlignHandler.reset();
  420. PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
  421. GCCVisibilityHandler.reset();
  422. PP.RemovePragmaHandler(OptionsHandler.get());
  423. OptionsHandler.reset();
  424. PP.RemovePragmaHandler(PackHandler.get());
  425. PackHandler.reset();
  426. PP.RemovePragmaHandler(MSStructHandler.get());
  427. MSStructHandler.reset();
  428. PP.RemovePragmaHandler(UnusedHandler.get());
  429. UnusedHandler.reset();
  430. PP.RemovePragmaHandler(WeakHandler.get());
  431. WeakHandler.reset();
  432. PP.RemovePragmaHandler(RedefineExtnameHandler.get());
  433. RedefineExtnameHandler.reset();
  434. if (getLangOpts().OpenCL) {
  435. PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
  436. OpenCLExtensionHandler.reset();
  437. PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
  438. }
  439. PP.RemovePragmaHandler(OpenMPHandler.get());
  440. OpenMPHandler.reset();
  441. if (getLangOpts().MicrosoftExt ||
  442. getTargetInfo().getTriple().isOSBinFormatELF()) {
  443. PP.RemovePragmaHandler(MSCommentHandler.get());
  444. MSCommentHandler.reset();
  445. }
  446. PP.RemovePragmaHandler("clang", PCSectionHandler.get());
  447. PCSectionHandler.reset();
  448. PP.RemovePragmaHandler(FloatControlHandler.get());
  449. FloatControlHandler.reset();
  450. if (getLangOpts().MicrosoftExt) {
  451. PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
  452. MSDetectMismatchHandler.reset();
  453. PP.RemovePragmaHandler(MSPointersToMembers.get());
  454. MSPointersToMembers.reset();
  455. PP.RemovePragmaHandler(MSVtorDisp.get());
  456. MSVtorDisp.reset();
  457. PP.RemovePragmaHandler(MSInitSeg.get());
  458. MSInitSeg.reset();
  459. PP.RemovePragmaHandler(MSDataSeg.get());
  460. MSDataSeg.reset();
  461. PP.RemovePragmaHandler(MSBSSSeg.get());
  462. MSBSSSeg.reset();
  463. PP.RemovePragmaHandler(MSConstSeg.get());
  464. MSConstSeg.reset();
  465. PP.RemovePragmaHandler(MSCodeSeg.get());
  466. MSCodeSeg.reset();
  467. PP.RemovePragmaHandler(MSSection.get());
  468. MSSection.reset();
  469. PP.RemovePragmaHandler(MSRuntimeChecks.get());
  470. MSRuntimeChecks.reset();
  471. PP.RemovePragmaHandler(MSIntrinsic.get());
  472. MSIntrinsic.reset();
  473. PP.RemovePragmaHandler(MSOptimize.get());
  474. MSOptimize.reset();
  475. PP.RemovePragmaHandler(MSFenvAccess.get());
  476. MSFenvAccess.reset();
  477. }
  478. if (getLangOpts().CUDA) {
  479. PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
  480. CUDAForceHostDeviceHandler.reset();
  481. }
  482. PP.RemovePragmaHandler("STDC", FPContractHandler.get());
  483. FPContractHandler.reset();
  484. PP.RemovePragmaHandler("STDC", STDCFenvAccessHandler.get());
  485. STDCFenvAccessHandler.reset();
  486. PP.RemovePragmaHandler("STDC", STDCFenvRoundHandler.get());
  487. STDCFenvRoundHandler.reset();
  488. PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get());
  489. STDCCXLIMITHandler.reset();
  490. PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
  491. STDCUnknownHandler.reset();
  492. PP.RemovePragmaHandler("clang", OptimizeHandler.get());
  493. OptimizeHandler.reset();
  494. PP.RemovePragmaHandler("clang", LoopHintHandler.get());
  495. LoopHintHandler.reset();
  496. PP.RemovePragmaHandler(UnrollHintHandler.get());
  497. PP.RemovePragmaHandler("GCC", UnrollHintHandler.get());
  498. UnrollHintHandler.reset();
  499. PP.RemovePragmaHandler(NoUnrollHintHandler.get());
  500. PP.RemovePragmaHandler("GCC", NoUnrollHintHandler.get());
  501. NoUnrollHintHandler.reset();
  502. PP.RemovePragmaHandler(UnrollAndJamHintHandler.get());
  503. UnrollAndJamHintHandler.reset();
  504. PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
  505. NoUnrollAndJamHintHandler.reset();
  506. PP.RemovePragmaHandler("clang", FPHandler.get());
  507. FPHandler.reset();
  508. PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
  509. AttributePragmaHandler.reset();
  510. PP.RemovePragmaHandler("clang", MaxTokensHerePragmaHandler.get());
  511. MaxTokensHerePragmaHandler.reset();
  512. PP.RemovePragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
  513. MaxTokensTotalPragmaHandler.reset();
  514. }
  515. /// Handle the annotation token produced for #pragma unused(...)
  516. ///
  517. /// Each annot_pragma_unused is followed by the argument token so e.g.
  518. /// "#pragma unused(x,y)" becomes:
  519. /// annot_pragma_unused 'x' annot_pragma_unused 'y'
  520. void Parser::HandlePragmaUnused() {
  521. assert(Tok.is(tok::annot_pragma_unused));
  522. SourceLocation UnusedLoc = ConsumeAnnotationToken();
  523. Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
  524. ConsumeToken(); // The argument token.
  525. }
  526. void Parser::HandlePragmaVisibility() {
  527. assert(Tok.is(tok::annot_pragma_vis));
  528. const IdentifierInfo *VisType =
  529. static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
  530. SourceLocation VisLoc = ConsumeAnnotationToken();
  531. Actions.ActOnPragmaVisibility(VisType, VisLoc);
  532. }
  533. namespace {
  534. struct PragmaPackInfo {
  535. Sema::PragmaMsStackAction Action;
  536. StringRef SlotLabel;
  537. Token Alignment;
  538. };
  539. } // end anonymous namespace
  540. void Parser::HandlePragmaPack() {
  541. assert(Tok.is(tok::annot_pragma_pack));
  542. PragmaPackInfo *Info =
  543. static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
  544. SourceLocation PragmaLoc = Tok.getLocation();
  545. ExprResult Alignment;
  546. if (Info->Alignment.is(tok::numeric_constant)) {
  547. Alignment = Actions.ActOnNumericConstant(Info->Alignment);
  548. if (Alignment.isInvalid()) {
  549. ConsumeAnnotationToken();
  550. return;
  551. }
  552. }
  553. Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
  554. Alignment.get());
  555. // Consume the token after processing the pragma to enable pragma-specific
  556. // #include warnings.
  557. ConsumeAnnotationToken();
  558. }
  559. void Parser::HandlePragmaMSStruct() {
  560. assert(Tok.is(tok::annot_pragma_msstruct));
  561. PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
  562. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  563. Actions.ActOnPragmaMSStruct(Kind);
  564. ConsumeAnnotationToken();
  565. }
  566. void Parser::HandlePragmaAlign() {
  567. assert(Tok.is(tok::annot_pragma_align));
  568. Sema::PragmaOptionsAlignKind Kind =
  569. static_cast<Sema::PragmaOptionsAlignKind>(
  570. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  571. Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
  572. // Consume the token after processing the pragma to enable pragma-specific
  573. // #include warnings.
  574. ConsumeAnnotationToken();
  575. }
  576. void Parser::HandlePragmaDump() {
  577. assert(Tok.is(tok::annot_pragma_dump));
  578. IdentifierInfo *II =
  579. reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
  580. Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
  581. ConsumeAnnotationToken();
  582. }
  583. void Parser::HandlePragmaWeak() {
  584. assert(Tok.is(tok::annot_pragma_weak));
  585. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  586. Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
  587. Tok.getLocation());
  588. ConsumeToken(); // The weak name.
  589. }
  590. void Parser::HandlePragmaWeakAlias() {
  591. assert(Tok.is(tok::annot_pragma_weakalias));
  592. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  593. IdentifierInfo *WeakName = Tok.getIdentifierInfo();
  594. SourceLocation WeakNameLoc = Tok.getLocation();
  595. ConsumeToken();
  596. IdentifierInfo *AliasName = Tok.getIdentifierInfo();
  597. SourceLocation AliasNameLoc = Tok.getLocation();
  598. ConsumeToken();
  599. Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
  600. WeakNameLoc, AliasNameLoc);
  601. }
  602. void Parser::HandlePragmaRedefineExtname() {
  603. assert(Tok.is(tok::annot_pragma_redefine_extname));
  604. SourceLocation RedefLoc = ConsumeAnnotationToken();
  605. IdentifierInfo *RedefName = Tok.getIdentifierInfo();
  606. SourceLocation RedefNameLoc = Tok.getLocation();
  607. ConsumeToken();
  608. IdentifierInfo *AliasName = Tok.getIdentifierInfo();
  609. SourceLocation AliasNameLoc = Tok.getLocation();
  610. ConsumeToken();
  611. Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
  612. RedefNameLoc, AliasNameLoc);
  613. }
  614. void Parser::HandlePragmaFPContract() {
  615. assert(Tok.is(tok::annot_pragma_fp_contract));
  616. tok::OnOffSwitch OOS =
  617. static_cast<tok::OnOffSwitch>(
  618. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  619. LangOptions::FPModeKind FPC;
  620. switch (OOS) {
  621. case tok::OOS_ON:
  622. FPC = LangOptions::FPM_On;
  623. break;
  624. case tok::OOS_OFF:
  625. FPC = LangOptions::FPM_Off;
  626. break;
  627. case tok::OOS_DEFAULT:
  628. FPC = getLangOpts().getDefaultFPContractMode();
  629. break;
  630. }
  631. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  632. Actions.ActOnPragmaFPContract(PragmaLoc, FPC);
  633. }
  634. void Parser::HandlePragmaFloatControl() {
  635. assert(Tok.is(tok::annot_pragma_float_control));
  636. // The value that is held on the PragmaFloatControlStack encodes
  637. // the PragmaFloatControl kind and the MSStackAction kind
  638. // into a single 32-bit word. The MsStackAction is the high 16 bits
  639. // and the FloatControl is the lower 16 bits. Use shift and bit-and
  640. // to decode the parts.
  641. uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
  642. Sema::PragmaMsStackAction Action =
  643. static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
  644. PragmaFloatControlKind Kind = PragmaFloatControlKind(Value & 0xFFFF);
  645. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  646. Actions.ActOnPragmaFloatControl(PragmaLoc, Action, Kind);
  647. }
  648. void Parser::HandlePragmaFEnvAccess() {
  649. assert(Tok.is(tok::annot_pragma_fenv_access) ||
  650. Tok.is(tok::annot_pragma_fenv_access_ms));
  651. tok::OnOffSwitch OOS =
  652. static_cast<tok::OnOffSwitch>(
  653. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  654. bool IsEnabled;
  655. switch (OOS) {
  656. case tok::OOS_ON:
  657. IsEnabled = true;
  658. break;
  659. case tok::OOS_OFF:
  660. IsEnabled = false;
  661. break;
  662. case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
  663. IsEnabled = false;
  664. break;
  665. }
  666. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  667. Actions.ActOnPragmaFEnvAccess(PragmaLoc, IsEnabled);
  668. }
  669. void Parser::HandlePragmaFEnvRound() {
  670. assert(Tok.is(tok::annot_pragma_fenv_round));
  671. auto RM = static_cast<llvm::RoundingMode>(
  672. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  673. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  674. Actions.setRoundingMode(PragmaLoc, RM);
  675. }
  676. StmtResult Parser::HandlePragmaCaptured()
  677. {
  678. assert(Tok.is(tok::annot_pragma_captured));
  679. ConsumeAnnotationToken();
  680. if (Tok.isNot(tok::l_brace)) {
  681. PP.Diag(Tok, diag::err_expected) << tok::l_brace;
  682. return StmtError();
  683. }
  684. SourceLocation Loc = Tok.getLocation();
  685. ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope |
  686. Scope::CompoundStmtScope);
  687. Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
  688. /*NumParams=*/1);
  689. StmtResult R = ParseCompoundStatement();
  690. CapturedRegionScope.Exit();
  691. if (R.isInvalid()) {
  692. Actions.ActOnCapturedRegionError();
  693. return StmtError();
  694. }
  695. return Actions.ActOnCapturedRegionEnd(R.get());
  696. }
  697. namespace {
  698. enum OpenCLExtState : char {
  699. Disable, Enable, Begin, End
  700. };
  701. typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
  702. }
  703. void Parser::HandlePragmaOpenCLExtension() {
  704. assert(Tok.is(tok::annot_pragma_opencl_extension));
  705. OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
  706. auto State = Data->second;
  707. auto Ident = Data->first;
  708. SourceLocation NameLoc = Tok.getLocation();
  709. ConsumeAnnotationToken();
  710. auto &Opt = Actions.getOpenCLOptions();
  711. auto Name = Ident->getName();
  712. // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
  713. // overriding all previously issued extension directives, but only if the
  714. // behavior is set to disable."
  715. if (Name == "all") {
  716. if (State == Disable)
  717. Opt.disableAll();
  718. else
  719. PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
  720. } else if (State == Begin) {
  721. if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
  722. Opt.support(Name);
  723. // FIXME: Default behavior of the extension pragma is not defined.
  724. // Therefore, it should never be added by default.
  725. Opt.acceptsPragma(Name);
  726. }
  727. } else if (State == End) {
  728. // There is no behavior for this directive. We only accept this for
  729. // backward compatibility.
  730. } else if (!Opt.isKnown(Name) || !Opt.isWithPragma(Name))
  731. PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
  732. else if (Opt.isSupportedExtension(Name, getLangOpts()))
  733. Opt.enable(Name, State == Enable);
  734. else if (Opt.isSupportedCoreOrOptionalCore(Name, getLangOpts()))
  735. PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
  736. else
  737. PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
  738. }
  739. void Parser::HandlePragmaMSPointersToMembers() {
  740. assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
  741. LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
  742. static_cast<LangOptions::PragmaMSPointersToMembersKind>(
  743. reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
  744. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  745. Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
  746. }
  747. void Parser::HandlePragmaMSVtorDisp() {
  748. assert(Tok.is(tok::annot_pragma_ms_vtordisp));
  749. uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
  750. Sema::PragmaMsStackAction Action =
  751. static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
  752. MSVtorDispMode Mode = MSVtorDispMode(Value & 0xFFFF);
  753. SourceLocation PragmaLoc = ConsumeAnnotationToken();
  754. Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
  755. }
  756. void Parser::HandlePragmaMSPragma() {
  757. assert(Tok.is(tok::annot_pragma_ms_pragma));
  758. // Grab the tokens out of the annotation and enter them into the stream.
  759. auto TheTokens =
  760. (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
  761. PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true,
  762. /*IsReinject=*/true);
  763. SourceLocation PragmaLocation = ConsumeAnnotationToken();
  764. assert(Tok.isAnyIdentifier());
  765. StringRef PragmaName = Tok.getIdentifierInfo()->getName();
  766. PP.Lex(Tok); // pragma kind
  767. // Figure out which #pragma we're dealing with. The switch has no default
  768. // because lex shouldn't emit the annotation token for unrecognized pragmas.
  769. typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
  770. PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
  771. .Case("data_seg", &Parser::HandlePragmaMSSegment)
  772. .Case("bss_seg", &Parser::HandlePragmaMSSegment)
  773. .Case("const_seg", &Parser::HandlePragmaMSSegment)
  774. .Case("code_seg", &Parser::HandlePragmaMSSegment)
  775. .Case("section", &Parser::HandlePragmaMSSection)
  776. .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
  777. if (!(this->*Handler)(PragmaName, PragmaLocation)) {
  778. // Pragma handling failed, and has been diagnosed. Slurp up the tokens
  779. // until eof (really end of line) to prevent follow-on errors.
  780. while (Tok.isNot(tok::eof))
  781. PP.Lex(Tok);
  782. PP.Lex(Tok);
  783. }
  784. }
  785. bool Parser::HandlePragmaMSSection(StringRef PragmaName,
  786. SourceLocation PragmaLocation) {
  787. if (Tok.isNot(tok::l_paren)) {
  788. PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
  789. return false;
  790. }
  791. PP.Lex(Tok); // (
  792. // Parsing code for pragma section
  793. if (Tok.isNot(tok::string_literal)) {
  794. PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
  795. << PragmaName;
  796. return false;
  797. }
  798. ExprResult StringResult = ParseStringLiteralExpression();
  799. if (StringResult.isInvalid())
  800. return false; // Already diagnosed.
  801. StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
  802. if (SegmentName->getCharByteWidth() != 1) {
  803. PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
  804. << PragmaName;
  805. return false;
  806. }
  807. int SectionFlags = ASTContext::PSF_Read;
  808. bool SectionFlagsAreDefault = true;
  809. while (Tok.is(tok::comma)) {
  810. PP.Lex(Tok); // ,
  811. // Ignore "long" and "short".
  812. // They are undocumented, but widely used, section attributes which appear
  813. // to do nothing.
  814. if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
  815. PP.Lex(Tok); // long/short
  816. continue;
  817. }
  818. if (!Tok.isAnyIdentifier()) {
  819. PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
  820. << PragmaName;
  821. return false;
  822. }
  823. ASTContext::PragmaSectionFlag Flag =
  824. llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
  825. Tok.getIdentifierInfo()->getName())
  826. .Case("read", ASTContext::PSF_Read)
  827. .Case("write", ASTContext::PSF_Write)
  828. .Case("execute", ASTContext::PSF_Execute)
  829. .Case("shared", ASTContext::PSF_Invalid)
  830. .Case("nopage", ASTContext::PSF_Invalid)
  831. .Case("nocache", ASTContext::PSF_Invalid)
  832. .Case("discard", ASTContext::PSF_Invalid)
  833. .Case("remove", ASTContext::PSF_Invalid)
  834. .Default(ASTContext::PSF_None);
  835. if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
  836. PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
  837. ? diag::warn_pragma_invalid_specific_action
  838. : diag::warn_pragma_unsupported_action)
  839. << PragmaName << Tok.getIdentifierInfo()->getName();
  840. return false;
  841. }
  842. SectionFlags |= Flag;
  843. SectionFlagsAreDefault = false;
  844. PP.Lex(Tok); // Identifier
  845. }
  846. // If no section attributes are specified, the section will be marked as
  847. // read/write.
  848. if (SectionFlagsAreDefault)
  849. SectionFlags |= ASTContext::PSF_Write;
  850. if (Tok.isNot(tok::r_paren)) {
  851. PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
  852. return false;
  853. }
  854. PP.Lex(Tok); // )
  855. if (Tok.isNot(tok::eof)) {
  856. PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
  857. << PragmaName;
  858. return false;
  859. }
  860. PP.Lex(Tok); // eof
  861. Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
  862. return true;
  863. }
  864. bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
  865. SourceLocation PragmaLocation) {
  866. if (Tok.isNot(tok::l_paren)) {
  867. PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
  868. return false;
  869. }
  870. PP.Lex(Tok); // (
  871. Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
  872. StringRef SlotLabel;
  873. if (Tok.isAnyIdentifier()) {
  874. StringRef PushPop = Tok.getIdentifierInfo()->getName();
  875. if (PushPop == "push")
  876. Action = Sema::PSK_Push;
  877. else if (PushPop == "pop")
  878. Action = Sema::PSK_Pop;
  879. else {
  880. PP.Diag(PragmaLocation,
  881. diag::warn_pragma_expected_section_push_pop_or_name)
  882. << PragmaName;
  883. return false;
  884. }
  885. if (Action != Sema::PSK_Reset) {
  886. PP.Lex(Tok); // push | pop
  887. if (Tok.is(tok::comma)) {
  888. PP.Lex(Tok); // ,
  889. // If we've got a comma, we either need a label or a string.
  890. if (Tok.isAnyIdentifier()) {
  891. SlotLabel = Tok.getIdentifierInfo()->getName();
  892. PP.Lex(Tok); // identifier
  893. if (Tok.is(tok::comma))
  894. PP.Lex(Tok);
  895. else if (Tok.isNot(tok::r_paren)) {
  896. PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
  897. << PragmaName;
  898. return false;
  899. }
  900. }
  901. } else if (Tok.isNot(tok::r_paren)) {
  902. PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
  903. return false;
  904. }
  905. }
  906. }
  907. // Grab the string literal for our section name.
  908. StringLiteral *SegmentName = nullptr;
  909. if (Tok.isNot(tok::r_paren)) {
  910. if (Tok.isNot(tok::string_literal)) {
  911. unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
  912. diag::warn_pragma_expected_section_name :
  913. diag::warn_pragma_expected_section_label_or_name :
  914. diag::warn_pragma_expected_section_push_pop_or_name;
  915. PP.Diag(PragmaLocation, DiagID) << PragmaName;
  916. return false;
  917. }
  918. ExprResult StringResult = ParseStringLiteralExpression();
  919. if (StringResult.isInvalid())
  920. return false; // Already diagnosed.
  921. SegmentName = cast<StringLiteral>(StringResult.get());
  922. if (SegmentName->getCharByteWidth() != 1) {
  923. PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
  924. << PragmaName;
  925. return false;
  926. }
  927. // Setting section "" has no effect
  928. if (SegmentName->getLength())
  929. Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
  930. }
  931. if (Tok.isNot(tok::r_paren)) {
  932. PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
  933. return false;
  934. }
  935. PP.Lex(Tok); // )
  936. if (Tok.isNot(tok::eof)) {
  937. PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
  938. << PragmaName;
  939. return false;
  940. }
  941. PP.Lex(Tok); // eof
  942. Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
  943. SegmentName, PragmaName);
  944. return true;
  945. }
  946. // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
  947. bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
  948. SourceLocation PragmaLocation) {
  949. if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
  950. PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
  951. return false;
  952. }
  953. if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
  954. PragmaName))
  955. return false;
  956. // Parse either the known section names or the string section name.
  957. StringLiteral *SegmentName = nullptr;
  958. if (Tok.isAnyIdentifier()) {
  959. auto *II = Tok.getIdentifierInfo();
  960. StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
  961. .Case("compiler", "\".CRT$XCC\"")
  962. .Case("lib", "\".CRT$XCL\"")
  963. .Case("user", "\".CRT$XCU\"")
  964. .Default("");
  965. if (!Section.empty()) {
  966. // Pretend the user wrote the appropriate string literal here.
  967. Token Toks[1];
  968. Toks[0].startToken();
  969. Toks[0].setKind(tok::string_literal);
  970. Toks[0].setLocation(Tok.getLocation());
  971. Toks[0].setLiteralData(Section.data());
  972. Toks[0].setLength(Section.size());
  973. SegmentName =
  974. cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
  975. PP.Lex(Tok);
  976. }
  977. } else if (Tok.is(tok::string_literal)) {
  978. ExprResult StringResult = ParseStringLiteralExpression();
  979. if (StringResult.isInvalid())
  980. return false;
  981. SegmentName = cast<StringLiteral>(StringResult.get());
  982. if (SegmentName->getCharByteWidth() != 1) {
  983. PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
  984. << PragmaName;
  985. return false;
  986. }
  987. // FIXME: Add support for the '[, func-name]' part of the pragma.
  988. }
  989. if (!SegmentName) {
  990. PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
  991. return false;
  992. }
  993. if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
  994. PragmaName) ||
  995. ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
  996. PragmaName))
  997. return false;
  998. Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
  999. return true;
  1000. }
  1001. namespace {
  1002. struct PragmaLoopHintInfo {
  1003. Token PragmaName;
  1004. Token Option;
  1005. ArrayRef<Token> Toks;
  1006. };
  1007. } // end anonymous namespace
  1008. static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
  1009. StringRef Str = PragmaName.getIdentifierInfo()->getName();
  1010. std::string ClangLoopStr = (llvm::Twine("clang loop ") + Str).str();
  1011. return std::string(llvm::StringSwitch<StringRef>(Str)
  1012. .Case("loop", ClangLoopStr)
  1013. .Case("unroll_and_jam", Str)
  1014. .Case("unroll", Str)
  1015. .Default(""));
  1016. }
  1017. bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
  1018. assert(Tok.is(tok::annot_pragma_loop_hint));
  1019. PragmaLoopHintInfo *Info =
  1020. static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
  1021. IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
  1022. Hint.PragmaNameLoc = IdentifierLoc::create(
  1023. Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
  1024. // It is possible that the loop hint has no option identifier, such as
  1025. // #pragma unroll(4).
  1026. IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
  1027. ? Info->Option.getIdentifierInfo()
  1028. : nullptr;
  1029. Hint.OptionLoc = IdentifierLoc::create(
  1030. Actions.Context, Info->Option.getLocation(), OptionInfo);
  1031. llvm::ArrayRef<Token> Toks = Info->Toks;
  1032. // Return a valid hint if pragma unroll or nounroll were specified
  1033. // without an argument.
  1034. auto IsLoopHint = llvm::StringSwitch<bool>(PragmaNameInfo->getName())
  1035. .Cases("unroll", "nounroll", "unroll_and_jam",
  1036. "nounroll_and_jam", true)
  1037. .Default(false);
  1038. if (Toks.empty() && IsLoopHint) {
  1039. ConsumeAnnotationToken();
  1040. Hint.Range = Info->PragmaName.getLocation();
  1041. return true;
  1042. }
  1043. // The constant expression is always followed by an eof token, which increases
  1044. // the TokSize by 1.
  1045. assert(!Toks.empty() &&
  1046. "PragmaLoopHintInfo::Toks must contain at least one token.");
  1047. // If no option is specified the argument is assumed to be a constant expr.
  1048. bool OptionUnroll = false;
  1049. bool OptionUnrollAndJam = false;
  1050. bool OptionDistribute = false;
  1051. bool OptionPipelineDisabled = false;
  1052. bool StateOption = false;
  1053. if (OptionInfo) { // Pragma Unroll does not specify an option.
  1054. OptionUnroll = OptionInfo->isStr("unroll");
  1055. OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
  1056. OptionDistribute = OptionInfo->isStr("distribute");
  1057. OptionPipelineDisabled = OptionInfo->isStr("pipeline");
  1058. StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
  1059. .Case("vectorize", true)
  1060. .Case("interleave", true)
  1061. .Case("vectorize_predicate", true)
  1062. .Default(false) ||
  1063. OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
  1064. OptionPipelineDisabled;
  1065. }
  1066. bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
  1067. !OptionDistribute && !OptionPipelineDisabled;
  1068. // Verify loop hint has an argument.
  1069. if (Toks[0].is(tok::eof)) {
  1070. ConsumeAnnotationToken();
  1071. Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
  1072. << /*StateArgument=*/StateOption
  1073. << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
  1074. << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
  1075. return false;
  1076. }
  1077. // Validate the argument.
  1078. if (StateOption) {
  1079. ConsumeAnnotationToken();
  1080. SourceLocation StateLoc = Toks[0].getLocation();
  1081. IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
  1082. bool Valid = StateInfo &&
  1083. llvm::StringSwitch<bool>(StateInfo->getName())
  1084. .Case("disable", true)
  1085. .Case("enable", !OptionPipelineDisabled)
  1086. .Case("full", OptionUnroll || OptionUnrollAndJam)
  1087. .Case("assume_safety", AssumeSafetyArg)
  1088. .Default(false);
  1089. if (!Valid) {
  1090. if (OptionPipelineDisabled) {
  1091. Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
  1092. } else {
  1093. Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
  1094. << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
  1095. << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
  1096. }
  1097. return false;
  1098. }
  1099. if (Toks.size() > 2)
  1100. Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1101. << PragmaLoopHintString(Info->PragmaName, Info->Option);
  1102. Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
  1103. } else if (OptionInfo && OptionInfo->getName() == "vectorize_width") {
  1104. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
  1105. /*IsReinject=*/false);
  1106. ConsumeAnnotationToken();
  1107. SourceLocation StateLoc = Toks[0].getLocation();
  1108. IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
  1109. StringRef IsScalableStr = StateInfo ? StateInfo->getName() : "";
  1110. // Look for vectorize_width(fixed|scalable)
  1111. if (IsScalableStr == "scalable" || IsScalableStr == "fixed") {
  1112. PP.Lex(Tok); // Identifier
  1113. if (Toks.size() > 2) {
  1114. Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1115. << PragmaLoopHintString(Info->PragmaName, Info->Option);
  1116. while (Tok.isNot(tok::eof))
  1117. ConsumeAnyToken();
  1118. }
  1119. Hint.StateLoc =
  1120. IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
  1121. ConsumeToken(); // Consume the constant expression eof terminator.
  1122. } else {
  1123. // Enter constant expression including eof terminator into token stream.
  1124. ExprResult R = ParseConstantExpression();
  1125. if (R.isInvalid() && !Tok.is(tok::comma))
  1126. Diag(Toks[0].getLocation(),
  1127. diag::note_pragma_loop_invalid_vectorize_option);
  1128. bool Arg2Error = false;
  1129. if (Tok.is(tok::comma)) {
  1130. PP.Lex(Tok); // ,
  1131. StateInfo = Tok.getIdentifierInfo();
  1132. IsScalableStr = StateInfo->getName();
  1133. if (IsScalableStr != "scalable" && IsScalableStr != "fixed") {
  1134. Diag(Tok.getLocation(),
  1135. diag::err_pragma_loop_invalid_vectorize_option);
  1136. Arg2Error = true;
  1137. } else
  1138. Hint.StateLoc =
  1139. IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
  1140. PP.Lex(Tok); // Identifier
  1141. }
  1142. // Tokens following an error in an ill-formed constant expression will
  1143. // remain in the token stream and must be removed.
  1144. if (Tok.isNot(tok::eof)) {
  1145. Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1146. << PragmaLoopHintString(Info->PragmaName, Info->Option);
  1147. while (Tok.isNot(tok::eof))
  1148. ConsumeAnyToken();
  1149. }
  1150. ConsumeToken(); // Consume the constant expression eof terminator.
  1151. if (Arg2Error || R.isInvalid() ||
  1152. Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
  1153. return false;
  1154. // Argument is a constant expression with an integer type.
  1155. Hint.ValueExpr = R.get();
  1156. }
  1157. } else {
  1158. // Enter constant expression including eof terminator into token stream.
  1159. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
  1160. /*IsReinject=*/false);
  1161. ConsumeAnnotationToken();
  1162. ExprResult R = ParseConstantExpression();
  1163. // Tokens following an error in an ill-formed constant expression will
  1164. // remain in the token stream and must be removed.
  1165. if (Tok.isNot(tok::eof)) {
  1166. Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1167. << PragmaLoopHintString(Info->PragmaName, Info->Option);
  1168. while (Tok.isNot(tok::eof))
  1169. ConsumeAnyToken();
  1170. }
  1171. ConsumeToken(); // Consume the constant expression eof terminator.
  1172. if (R.isInvalid() ||
  1173. Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
  1174. return false;
  1175. // Argument is a constant expression with an integer type.
  1176. Hint.ValueExpr = R.get();
  1177. }
  1178. Hint.Range = SourceRange(Info->PragmaName.getLocation(),
  1179. Info->Toks.back().getLocation());
  1180. return true;
  1181. }
  1182. namespace {
  1183. struct PragmaAttributeInfo {
  1184. enum ActionType { Push, Pop, Attribute };
  1185. ParsedAttributes &Attributes;
  1186. ActionType Action;
  1187. const IdentifierInfo *Namespace = nullptr;
  1188. ArrayRef<Token> Tokens;
  1189. PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
  1190. };
  1191. #include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
  1192. } // end anonymous namespace
  1193. static StringRef getIdentifier(const Token &Tok) {
  1194. if (Tok.is(tok::identifier))
  1195. return Tok.getIdentifierInfo()->getName();
  1196. const char *S = tok::getKeywordSpelling(Tok.getKind());
  1197. if (!S)
  1198. return "";
  1199. return S;
  1200. }
  1201. static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
  1202. using namespace attr;
  1203. switch (Rule) {
  1204. #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
  1205. case Value: \
  1206. return IsAbstract;
  1207. #include "clang/Basic/AttrSubMatchRulesList.inc"
  1208. }
  1209. llvm_unreachable("Invalid attribute subject match rule");
  1210. return false;
  1211. }
  1212. static void diagnoseExpectedAttributeSubjectSubRule(
  1213. Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
  1214. SourceLocation SubRuleLoc) {
  1215. auto Diagnostic =
  1216. PRef.Diag(SubRuleLoc,
  1217. diag::err_pragma_attribute_expected_subject_sub_identifier)
  1218. << PrimaryRuleName;
  1219. if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
  1220. Diagnostic << /*SubRulesSupported=*/1 << SubRules;
  1221. else
  1222. Diagnostic << /*SubRulesSupported=*/0;
  1223. }
  1224. static void diagnoseUnknownAttributeSubjectSubRule(
  1225. Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
  1226. StringRef SubRuleName, SourceLocation SubRuleLoc) {
  1227. auto Diagnostic =
  1228. PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
  1229. << SubRuleName << PrimaryRuleName;
  1230. if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
  1231. Diagnostic << /*SubRulesSupported=*/1 << SubRules;
  1232. else
  1233. Diagnostic << /*SubRulesSupported=*/0;
  1234. }
  1235. bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
  1236. attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
  1237. SourceLocation &LastMatchRuleEndLoc) {
  1238. bool IsAny = false;
  1239. BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
  1240. if (getIdentifier(Tok) == "any") {
  1241. AnyLoc = ConsumeToken();
  1242. IsAny = true;
  1243. if (AnyParens.expectAndConsume())
  1244. return true;
  1245. }
  1246. do {
  1247. // Parse the subject matcher rule.
  1248. StringRef Name = getIdentifier(Tok);
  1249. if (Name.empty()) {
  1250. Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
  1251. return true;
  1252. }
  1253. std::pair<Optional<attr::SubjectMatchRule>,
  1254. Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
  1255. Rule = isAttributeSubjectMatchRule(Name);
  1256. if (!Rule.first) {
  1257. Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
  1258. return true;
  1259. }
  1260. attr::SubjectMatchRule PrimaryRule = *Rule.first;
  1261. SourceLocation RuleLoc = ConsumeToken();
  1262. BalancedDelimiterTracker Parens(*this, tok::l_paren);
  1263. if (isAbstractAttrMatcherRule(PrimaryRule)) {
  1264. if (Parens.expectAndConsume())
  1265. return true;
  1266. } else if (Parens.consumeOpen()) {
  1267. if (!SubjectMatchRules
  1268. .insert(
  1269. std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
  1270. .second)
  1271. Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
  1272. << Name
  1273. << FixItHint::CreateRemoval(SourceRange(
  1274. RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
  1275. LastMatchRuleEndLoc = RuleLoc;
  1276. continue;
  1277. }
  1278. // Parse the sub-rules.
  1279. StringRef SubRuleName = getIdentifier(Tok);
  1280. if (SubRuleName.empty()) {
  1281. diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
  1282. Tok.getLocation());
  1283. return true;
  1284. }
  1285. attr::SubjectMatchRule SubRule;
  1286. if (SubRuleName == "unless") {
  1287. SourceLocation SubRuleLoc = ConsumeToken();
  1288. BalancedDelimiterTracker Parens(*this, tok::l_paren);
  1289. if (Parens.expectAndConsume())
  1290. return true;
  1291. SubRuleName = getIdentifier(Tok);
  1292. if (SubRuleName.empty()) {
  1293. diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
  1294. SubRuleLoc);
  1295. return true;
  1296. }
  1297. auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
  1298. if (!SubRuleOrNone) {
  1299. std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
  1300. diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
  1301. SubRuleUnlessName, SubRuleLoc);
  1302. return true;
  1303. }
  1304. SubRule = *SubRuleOrNone;
  1305. ConsumeToken();
  1306. if (Parens.consumeClose())
  1307. return true;
  1308. } else {
  1309. auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
  1310. if (!SubRuleOrNone) {
  1311. diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
  1312. SubRuleName, Tok.getLocation());
  1313. return true;
  1314. }
  1315. SubRule = *SubRuleOrNone;
  1316. ConsumeToken();
  1317. }
  1318. SourceLocation RuleEndLoc = Tok.getLocation();
  1319. LastMatchRuleEndLoc = RuleEndLoc;
  1320. if (Parens.consumeClose())
  1321. return true;
  1322. if (!SubjectMatchRules
  1323. .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
  1324. .second) {
  1325. Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
  1326. << attr::getSubjectMatchRuleSpelling(SubRule)
  1327. << FixItHint::CreateRemoval(SourceRange(
  1328. RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
  1329. continue;
  1330. }
  1331. } while (IsAny && TryConsumeToken(tok::comma));
  1332. if (IsAny)
  1333. if (AnyParens.consumeClose())
  1334. return true;
  1335. return false;
  1336. }
  1337. namespace {
  1338. /// Describes the stage at which attribute subject rule parsing was interrupted.
  1339. enum class MissingAttributeSubjectRulesRecoveryPoint {
  1340. Comma,
  1341. ApplyTo,
  1342. Equals,
  1343. Any,
  1344. None,
  1345. };
  1346. MissingAttributeSubjectRulesRecoveryPoint
  1347. getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
  1348. if (const auto *II = Tok.getIdentifierInfo()) {
  1349. if (II->isStr("apply_to"))
  1350. return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
  1351. if (II->isStr("any"))
  1352. return MissingAttributeSubjectRulesRecoveryPoint::Any;
  1353. }
  1354. if (Tok.is(tok::equal))
  1355. return MissingAttributeSubjectRulesRecoveryPoint::Equals;
  1356. return MissingAttributeSubjectRulesRecoveryPoint::None;
  1357. }
  1358. /// Creates a diagnostic for the attribute subject rule parsing diagnostic that
  1359. /// suggests the possible attribute subject rules in a fix-it together with
  1360. /// any other missing tokens.
  1361. DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
  1362. unsigned DiagID, ParsedAttr &Attribute,
  1363. MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
  1364. SourceLocation Loc = PRef.getEndOfPreviousToken();
  1365. if (Loc.isInvalid())
  1366. Loc = PRef.getCurToken().getLocation();
  1367. auto Diagnostic = PRef.Diag(Loc, DiagID);
  1368. std::string FixIt;
  1369. MissingAttributeSubjectRulesRecoveryPoint EndPoint =
  1370. getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
  1371. if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
  1372. FixIt = ", ";
  1373. if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
  1374. EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
  1375. FixIt += "apply_to";
  1376. if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
  1377. EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
  1378. FixIt += " = ";
  1379. SourceRange FixItRange(Loc);
  1380. if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
  1381. // Gather the subject match rules that are supported by the attribute.
  1382. SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
  1383. Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
  1384. if (SubjectMatchRuleSet.empty()) {
  1385. // FIXME: We can emit a "fix-it" with a subject list placeholder when
  1386. // placeholders will be supported by the fix-its.
  1387. return Diagnostic;
  1388. }
  1389. FixIt += "any(";
  1390. bool NeedsComma = false;
  1391. for (const auto &I : SubjectMatchRuleSet) {
  1392. // Ensure that the missing rule is reported in the fix-it only when it's
  1393. // supported in the current language mode.
  1394. if (!I.second)
  1395. continue;
  1396. if (NeedsComma)
  1397. FixIt += ", ";
  1398. else
  1399. NeedsComma = true;
  1400. FixIt += attr::getSubjectMatchRuleSpelling(I.first);
  1401. }
  1402. FixIt += ")";
  1403. // Check if we need to remove the range
  1404. PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
  1405. FixItRange.setEnd(PRef.getCurToken().getLocation());
  1406. }
  1407. if (FixItRange.getBegin() == FixItRange.getEnd())
  1408. Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
  1409. else
  1410. Diagnostic << FixItHint::CreateReplacement(
  1411. CharSourceRange::getCharRange(FixItRange), FixIt);
  1412. return Diagnostic;
  1413. }
  1414. } // end anonymous namespace
  1415. void Parser::HandlePragmaAttribute() {
  1416. assert(Tok.is(tok::annot_pragma_attribute) &&
  1417. "Expected #pragma attribute annotation token");
  1418. SourceLocation PragmaLoc = Tok.getLocation();
  1419. auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
  1420. if (Info->Action == PragmaAttributeInfo::Pop) {
  1421. ConsumeAnnotationToken();
  1422. Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
  1423. return;
  1424. }
  1425. // Parse the actual attribute with its arguments.
  1426. assert((Info->Action == PragmaAttributeInfo::Push ||
  1427. Info->Action == PragmaAttributeInfo::Attribute) &&
  1428. "Unexpected #pragma attribute command");
  1429. if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
  1430. ConsumeAnnotationToken();
  1431. Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
  1432. return;
  1433. }
  1434. PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false,
  1435. /*IsReinject=*/false);
  1436. ConsumeAnnotationToken();
  1437. ParsedAttributes &Attrs = Info->Attributes;
  1438. Attrs.clearListOnly();
  1439. auto SkipToEnd = [this]() {
  1440. SkipUntil(tok::eof, StopBeforeMatch);
  1441. ConsumeToken();
  1442. };
  1443. if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
  1444. // Parse the CXX11 style attribute.
  1445. ParseCXX11AttributeSpecifier(Attrs);
  1446. } else if (Tok.is(tok::kw___attribute)) {
  1447. ConsumeToken();
  1448. if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
  1449. "attribute"))
  1450. return SkipToEnd();
  1451. if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
  1452. return SkipToEnd();
  1453. // FIXME: The practical usefulness of completion here is limited because
  1454. // we only get here if the line has balanced parens.
  1455. if (Tok.is(tok::code_completion)) {
  1456. cutOffParsing();
  1457. // FIXME: suppress completion of unsupported attributes?
  1458. Actions.CodeCompleteAttribute(AttributeCommonInfo::Syntax::AS_GNU);
  1459. return SkipToEnd();
  1460. }
  1461. if (Tok.isNot(tok::identifier)) {
  1462. Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
  1463. SkipToEnd();
  1464. return;
  1465. }
  1466. IdentifierInfo *AttrName = Tok.getIdentifierInfo();
  1467. SourceLocation AttrNameLoc = ConsumeToken();
  1468. if (Tok.isNot(tok::l_paren))
  1469. Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
  1470. ParsedAttr::AS_GNU);
  1471. else
  1472. ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
  1473. /*ScopeName=*/nullptr,
  1474. /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
  1475. /*Declarator=*/nullptr);
  1476. if (ExpectAndConsume(tok::r_paren))
  1477. return SkipToEnd();
  1478. if (ExpectAndConsume(tok::r_paren))
  1479. return SkipToEnd();
  1480. } else if (Tok.is(tok::kw___declspec)) {
  1481. ParseMicrosoftDeclSpecs(Attrs);
  1482. } else {
  1483. Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
  1484. if (Tok.getIdentifierInfo()) {
  1485. // If we suspect that this is an attribute suggest the use of
  1486. // '__attribute__'.
  1487. if (ParsedAttr::getParsedKind(
  1488. Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
  1489. ParsedAttr::AS_GNU) != ParsedAttr::UnknownAttribute) {
  1490. SourceLocation InsertStartLoc = Tok.getLocation();
  1491. ConsumeToken();
  1492. if (Tok.is(tok::l_paren)) {
  1493. ConsumeAnyToken();
  1494. SkipUntil(tok::r_paren, StopBeforeMatch);
  1495. if (Tok.isNot(tok::r_paren))
  1496. return SkipToEnd();
  1497. }
  1498. Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
  1499. << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
  1500. << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
  1501. }
  1502. }
  1503. SkipToEnd();
  1504. return;
  1505. }
  1506. if (Attrs.empty() || Attrs.begin()->isInvalid()) {
  1507. SkipToEnd();
  1508. return;
  1509. }
  1510. // Ensure that we don't have more than one attribute.
  1511. if (Attrs.size() > 1) {
  1512. SourceLocation Loc = Attrs[1].getLoc();
  1513. Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
  1514. SkipToEnd();
  1515. return;
  1516. }
  1517. ParsedAttr &Attribute = *Attrs.begin();
  1518. if (!Attribute.isSupportedByPragmaAttribute()) {
  1519. Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
  1520. << Attribute;
  1521. SkipToEnd();
  1522. return;
  1523. }
  1524. // Parse the subject-list.
  1525. if (!TryConsumeToken(tok::comma)) {
  1526. createExpectedAttributeSubjectRulesTokenDiagnostic(
  1527. diag::err_expected, Attribute,
  1528. MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
  1529. << tok::comma;
  1530. SkipToEnd();
  1531. return;
  1532. }
  1533. if (Tok.isNot(tok::identifier)) {
  1534. createExpectedAttributeSubjectRulesTokenDiagnostic(
  1535. diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
  1536. MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
  1537. SkipToEnd();
  1538. return;
  1539. }
  1540. const IdentifierInfo *II = Tok.getIdentifierInfo();
  1541. if (!II->isStr("apply_to")) {
  1542. createExpectedAttributeSubjectRulesTokenDiagnostic(
  1543. diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
  1544. MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
  1545. SkipToEnd();
  1546. return;
  1547. }
  1548. ConsumeToken();
  1549. if (!TryConsumeToken(tok::equal)) {
  1550. createExpectedAttributeSubjectRulesTokenDiagnostic(
  1551. diag::err_expected, Attribute,
  1552. MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
  1553. << tok::equal;
  1554. SkipToEnd();
  1555. return;
  1556. }
  1557. attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
  1558. SourceLocation AnyLoc, LastMatchRuleEndLoc;
  1559. if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
  1560. LastMatchRuleEndLoc)) {
  1561. SkipToEnd();
  1562. return;
  1563. }
  1564. // Tokens following an ill-formed attribute will remain in the token stream
  1565. // and must be removed.
  1566. if (Tok.isNot(tok::eof)) {
  1567. Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
  1568. SkipToEnd();
  1569. return;
  1570. }
  1571. // Consume the eof terminator token.
  1572. ConsumeToken();
  1573. // Handle a mixed push/attribute by desurging to a push, then an attribute.
  1574. if (Info->Action == PragmaAttributeInfo::Push)
  1575. Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
  1576. Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
  1577. std::move(SubjectMatchRules));
  1578. }
  1579. // #pragma GCC visibility comes in two variants:
  1580. // 'push' '(' [visibility] ')'
  1581. // 'pop'
  1582. void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
  1583. PragmaIntroducer Introducer,
  1584. Token &VisTok) {
  1585. SourceLocation VisLoc = VisTok.getLocation();
  1586. Token Tok;
  1587. PP.LexUnexpandedToken(Tok);
  1588. const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
  1589. const IdentifierInfo *VisType;
  1590. if (PushPop && PushPop->isStr("pop")) {
  1591. VisType = nullptr;
  1592. } else if (PushPop && PushPop->isStr("push")) {
  1593. PP.LexUnexpandedToken(Tok);
  1594. if (Tok.isNot(tok::l_paren)) {
  1595. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
  1596. << "visibility";
  1597. return;
  1598. }
  1599. PP.LexUnexpandedToken(Tok);
  1600. VisType = Tok.getIdentifierInfo();
  1601. if (!VisType) {
  1602. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  1603. << "visibility";
  1604. return;
  1605. }
  1606. PP.LexUnexpandedToken(Tok);
  1607. if (Tok.isNot(tok::r_paren)) {
  1608. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
  1609. << "visibility";
  1610. return;
  1611. }
  1612. } else {
  1613. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  1614. << "visibility";
  1615. return;
  1616. }
  1617. SourceLocation EndLoc = Tok.getLocation();
  1618. PP.LexUnexpandedToken(Tok);
  1619. if (Tok.isNot(tok::eod)) {
  1620. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1621. << "visibility";
  1622. return;
  1623. }
  1624. auto Toks = std::make_unique<Token[]>(1);
  1625. Toks[0].startToken();
  1626. Toks[0].setKind(tok::annot_pragma_vis);
  1627. Toks[0].setLocation(VisLoc);
  1628. Toks[0].setAnnotationEndLoc(EndLoc);
  1629. Toks[0].setAnnotationValue(
  1630. const_cast<void *>(static_cast<const void *>(VisType)));
  1631. PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true,
  1632. /*IsReinject=*/false);
  1633. }
  1634. // #pragma pack(...) comes in the following delicious flavors:
  1635. // pack '(' [integer] ')'
  1636. // pack '(' 'show' ')'
  1637. // pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
  1638. void PragmaPackHandler::HandlePragma(Preprocessor &PP,
  1639. PragmaIntroducer Introducer,
  1640. Token &PackTok) {
  1641. SourceLocation PackLoc = PackTok.getLocation();
  1642. Token Tok;
  1643. PP.Lex(Tok);
  1644. if (Tok.isNot(tok::l_paren)) {
  1645. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
  1646. return;
  1647. }
  1648. Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
  1649. StringRef SlotLabel;
  1650. Token Alignment;
  1651. Alignment.startToken();
  1652. PP.Lex(Tok);
  1653. if (Tok.is(tok::numeric_constant)) {
  1654. Alignment = Tok;
  1655. PP.Lex(Tok);
  1656. // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
  1657. // the push/pop stack.
  1658. // In Apple gcc/XL, #pragma pack(4) is equivalent to #pragma pack(push, 4)
  1659. Action = (PP.getLangOpts().ApplePragmaPack || PP.getLangOpts().XLPragmaPack)
  1660. ? Sema::PSK_Push_Set
  1661. : Sema::PSK_Set;
  1662. } else if (Tok.is(tok::identifier)) {
  1663. const IdentifierInfo *II = Tok.getIdentifierInfo();
  1664. if (II->isStr("show")) {
  1665. Action = Sema::PSK_Show;
  1666. PP.Lex(Tok);
  1667. } else {
  1668. if (II->isStr("push")) {
  1669. Action = Sema::PSK_Push;
  1670. } else if (II->isStr("pop")) {
  1671. Action = Sema::PSK_Pop;
  1672. } else {
  1673. PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
  1674. return;
  1675. }
  1676. PP.Lex(Tok);
  1677. if (Tok.is(tok::comma)) {
  1678. PP.Lex(Tok);
  1679. if (Tok.is(tok::numeric_constant)) {
  1680. Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
  1681. Alignment = Tok;
  1682. PP.Lex(Tok);
  1683. } else if (Tok.is(tok::identifier)) {
  1684. SlotLabel = Tok.getIdentifierInfo()->getName();
  1685. PP.Lex(Tok);
  1686. if (Tok.is(tok::comma)) {
  1687. PP.Lex(Tok);
  1688. if (Tok.isNot(tok::numeric_constant)) {
  1689. PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
  1690. return;
  1691. }
  1692. Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
  1693. Alignment = Tok;
  1694. PP.Lex(Tok);
  1695. }
  1696. } else {
  1697. PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
  1698. return;
  1699. }
  1700. }
  1701. }
  1702. } else if (PP.getLangOpts().ApplePragmaPack ||
  1703. PP.getLangOpts().XLPragmaPack) {
  1704. // In MSVC/gcc, #pragma pack() resets the alignment without affecting
  1705. // the push/pop stack.
  1706. // In Apple gcc and IBM XL, #pragma pack() is equivalent to #pragma
  1707. // pack(pop).
  1708. Action = Sema::PSK_Pop;
  1709. }
  1710. if (Tok.isNot(tok::r_paren)) {
  1711. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
  1712. return;
  1713. }
  1714. SourceLocation RParenLoc = Tok.getLocation();
  1715. PP.Lex(Tok);
  1716. if (Tok.isNot(tok::eod)) {
  1717. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
  1718. return;
  1719. }
  1720. PragmaPackInfo *Info =
  1721. PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
  1722. Info->Action = Action;
  1723. Info->SlotLabel = SlotLabel;
  1724. Info->Alignment = Alignment;
  1725. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  1726. 1);
  1727. Toks[0].startToken();
  1728. Toks[0].setKind(tok::annot_pragma_pack);
  1729. Toks[0].setLocation(PackLoc);
  1730. Toks[0].setAnnotationEndLoc(RParenLoc);
  1731. Toks[0].setAnnotationValue(static_cast<void*>(Info));
  1732. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  1733. /*IsReinject=*/false);
  1734. }
  1735. // #pragma ms_struct on
  1736. // #pragma ms_struct off
  1737. void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
  1738. PragmaIntroducer Introducer,
  1739. Token &MSStructTok) {
  1740. PragmaMSStructKind Kind = PMSST_OFF;
  1741. Token Tok;
  1742. PP.Lex(Tok);
  1743. if (Tok.isNot(tok::identifier)) {
  1744. PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
  1745. return;
  1746. }
  1747. SourceLocation EndLoc = Tok.getLocation();
  1748. const IdentifierInfo *II = Tok.getIdentifierInfo();
  1749. if (II->isStr("on")) {
  1750. Kind = PMSST_ON;
  1751. PP.Lex(Tok);
  1752. }
  1753. else if (II->isStr("off") || II->isStr("reset"))
  1754. PP.Lex(Tok);
  1755. else {
  1756. PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
  1757. return;
  1758. }
  1759. if (Tok.isNot(tok::eod)) {
  1760. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1761. << "ms_struct";
  1762. return;
  1763. }
  1764. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  1765. 1);
  1766. Toks[0].startToken();
  1767. Toks[0].setKind(tok::annot_pragma_msstruct);
  1768. Toks[0].setLocation(MSStructTok.getLocation());
  1769. Toks[0].setAnnotationEndLoc(EndLoc);
  1770. Toks[0].setAnnotationValue(reinterpret_cast<void*>(
  1771. static_cast<uintptr_t>(Kind)));
  1772. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  1773. /*IsReinject=*/false);
  1774. }
  1775. // #pragma clang section bss="abc" data="" rodata="def" text="" relro=""
  1776. void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
  1777. PragmaIntroducer Introducer,
  1778. Token &FirstToken) {
  1779. Token Tok;
  1780. auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
  1781. PP.Lex(Tok); // eat 'section'
  1782. while (Tok.isNot(tok::eod)) {
  1783. if (Tok.isNot(tok::identifier)) {
  1784. PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
  1785. return;
  1786. }
  1787. const IdentifierInfo *SecType = Tok.getIdentifierInfo();
  1788. if (SecType->isStr("bss"))
  1789. SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
  1790. else if (SecType->isStr("data"))
  1791. SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
  1792. else if (SecType->isStr("rodata"))
  1793. SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
  1794. else if (SecType->isStr("relro"))
  1795. SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
  1796. else if (SecType->isStr("text"))
  1797. SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
  1798. else {
  1799. PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
  1800. return;
  1801. }
  1802. SourceLocation PragmaLocation = Tok.getLocation();
  1803. PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
  1804. if (Tok.isNot(tok::equal)) {
  1805. PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
  1806. return;
  1807. }
  1808. std::string SecName;
  1809. if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
  1810. return;
  1811. Actions.ActOnPragmaClangSection(
  1812. PragmaLocation,
  1813. (SecName.size() ? Sema::PragmaClangSectionAction::PCSA_Set
  1814. : Sema::PragmaClangSectionAction::PCSA_Clear),
  1815. SecKind, SecName);
  1816. }
  1817. }
  1818. // #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
  1819. // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
  1820. // #pragma 'align' '(' {'native','natural','mac68k','power','reset'} ')'
  1821. static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
  1822. bool IsOptions) {
  1823. Token Tok;
  1824. if (IsOptions) {
  1825. PP.Lex(Tok);
  1826. if (Tok.isNot(tok::identifier) ||
  1827. !Tok.getIdentifierInfo()->isStr("align")) {
  1828. PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
  1829. return;
  1830. }
  1831. }
  1832. PP.Lex(Tok);
  1833. if (PP.getLangOpts().XLPragmaPack) {
  1834. if (Tok.isNot(tok::l_paren)) {
  1835. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "align";
  1836. return;
  1837. }
  1838. } else if (Tok.isNot(tok::equal)) {
  1839. PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
  1840. << IsOptions;
  1841. return;
  1842. }
  1843. PP.Lex(Tok);
  1844. if (Tok.isNot(tok::identifier)) {
  1845. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  1846. << (IsOptions ? "options" : "align");
  1847. return;
  1848. }
  1849. Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
  1850. const IdentifierInfo *II = Tok.getIdentifierInfo();
  1851. if (II->isStr("native"))
  1852. Kind = Sema::POAK_Native;
  1853. else if (II->isStr("natural"))
  1854. Kind = Sema::POAK_Natural;
  1855. else if (II->isStr("packed"))
  1856. Kind = Sema::POAK_Packed;
  1857. else if (II->isStr("power"))
  1858. Kind = Sema::POAK_Power;
  1859. else if (II->isStr("mac68k"))
  1860. Kind = Sema::POAK_Mac68k;
  1861. else if (II->isStr("reset"))
  1862. Kind = Sema::POAK_Reset;
  1863. else {
  1864. PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
  1865. << IsOptions;
  1866. return;
  1867. }
  1868. if (PP.getLangOpts().XLPragmaPack) {
  1869. PP.Lex(Tok);
  1870. if (Tok.isNot(tok::r_paren)) {
  1871. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "align";
  1872. return;
  1873. }
  1874. }
  1875. SourceLocation EndLoc = Tok.getLocation();
  1876. PP.Lex(Tok);
  1877. if (Tok.isNot(tok::eod)) {
  1878. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  1879. << (IsOptions ? "options" : "align");
  1880. return;
  1881. }
  1882. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  1883. 1);
  1884. Toks[0].startToken();
  1885. Toks[0].setKind(tok::annot_pragma_align);
  1886. Toks[0].setLocation(FirstTok.getLocation());
  1887. Toks[0].setAnnotationEndLoc(EndLoc);
  1888. Toks[0].setAnnotationValue(reinterpret_cast<void*>(
  1889. static_cast<uintptr_t>(Kind)));
  1890. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  1891. /*IsReinject=*/false);
  1892. }
  1893. void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
  1894. PragmaIntroducer Introducer,
  1895. Token &AlignTok) {
  1896. ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
  1897. }
  1898. void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
  1899. PragmaIntroducer Introducer,
  1900. Token &OptionsTok) {
  1901. ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
  1902. }
  1903. // #pragma unused(identifier)
  1904. void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
  1905. PragmaIntroducer Introducer,
  1906. Token &UnusedTok) {
  1907. // FIXME: Should we be expanding macros here? My guess is no.
  1908. SourceLocation UnusedLoc = UnusedTok.getLocation();
  1909. // Lex the left '('.
  1910. Token Tok;
  1911. PP.Lex(Tok);
  1912. if (Tok.isNot(tok::l_paren)) {
  1913. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
  1914. return;
  1915. }
  1916. // Lex the declaration reference(s).
  1917. SmallVector<Token, 5> Identifiers;
  1918. SourceLocation RParenLoc;
  1919. bool LexID = true;
  1920. while (true) {
  1921. PP.Lex(Tok);
  1922. if (LexID) {
  1923. if (Tok.is(tok::identifier)) {
  1924. Identifiers.push_back(Tok);
  1925. LexID = false;
  1926. continue;
  1927. }
  1928. // Illegal token!
  1929. PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
  1930. return;
  1931. }
  1932. // We are execting a ')' or a ','.
  1933. if (Tok.is(tok::comma)) {
  1934. LexID = true;
  1935. continue;
  1936. }
  1937. if (Tok.is(tok::r_paren)) {
  1938. RParenLoc = Tok.getLocation();
  1939. break;
  1940. }
  1941. // Illegal token!
  1942. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
  1943. return;
  1944. }
  1945. PP.Lex(Tok);
  1946. if (Tok.isNot(tok::eod)) {
  1947. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
  1948. "unused";
  1949. return;
  1950. }
  1951. // Verify that we have a location for the right parenthesis.
  1952. assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
  1953. assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
  1954. // For each identifier token, insert into the token stream a
  1955. // annot_pragma_unused token followed by the identifier token.
  1956. // This allows us to cache a "#pragma unused" that occurs inside an inline
  1957. // C++ member function.
  1958. MutableArrayRef<Token> Toks(
  1959. PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
  1960. 2 * Identifiers.size());
  1961. for (unsigned i=0; i != Identifiers.size(); i++) {
  1962. Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
  1963. pragmaUnusedTok.startToken();
  1964. pragmaUnusedTok.setKind(tok::annot_pragma_unused);
  1965. pragmaUnusedTok.setLocation(UnusedLoc);
  1966. idTok = Identifiers[i];
  1967. }
  1968. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  1969. /*IsReinject=*/false);
  1970. }
  1971. // #pragma weak identifier
  1972. // #pragma weak identifier '=' identifier
  1973. void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
  1974. PragmaIntroducer Introducer,
  1975. Token &WeakTok) {
  1976. SourceLocation WeakLoc = WeakTok.getLocation();
  1977. Token Tok;
  1978. PP.Lex(Tok);
  1979. if (Tok.isNot(tok::identifier)) {
  1980. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
  1981. return;
  1982. }
  1983. Token WeakName = Tok;
  1984. bool HasAlias = false;
  1985. Token AliasName;
  1986. PP.Lex(Tok);
  1987. if (Tok.is(tok::equal)) {
  1988. HasAlias = true;
  1989. PP.Lex(Tok);
  1990. if (Tok.isNot(tok::identifier)) {
  1991. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  1992. << "weak";
  1993. return;
  1994. }
  1995. AliasName = Tok;
  1996. PP.Lex(Tok);
  1997. }
  1998. if (Tok.isNot(tok::eod)) {
  1999. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
  2000. return;
  2001. }
  2002. if (HasAlias) {
  2003. MutableArrayRef<Token> Toks(
  2004. PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
  2005. Token &pragmaUnusedTok = Toks[0];
  2006. pragmaUnusedTok.startToken();
  2007. pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
  2008. pragmaUnusedTok.setLocation(WeakLoc);
  2009. pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
  2010. Toks[1] = WeakName;
  2011. Toks[2] = AliasName;
  2012. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2013. /*IsReinject=*/false);
  2014. } else {
  2015. MutableArrayRef<Token> Toks(
  2016. PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
  2017. Token &pragmaUnusedTok = Toks[0];
  2018. pragmaUnusedTok.startToken();
  2019. pragmaUnusedTok.setKind(tok::annot_pragma_weak);
  2020. pragmaUnusedTok.setLocation(WeakLoc);
  2021. pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
  2022. Toks[1] = WeakName;
  2023. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2024. /*IsReinject=*/false);
  2025. }
  2026. }
  2027. // #pragma redefine_extname identifier identifier
  2028. void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
  2029. PragmaIntroducer Introducer,
  2030. Token &RedefToken) {
  2031. SourceLocation RedefLoc = RedefToken.getLocation();
  2032. Token Tok;
  2033. PP.Lex(Tok);
  2034. if (Tok.isNot(tok::identifier)) {
  2035. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
  2036. "redefine_extname";
  2037. return;
  2038. }
  2039. Token RedefName = Tok;
  2040. PP.Lex(Tok);
  2041. if (Tok.isNot(tok::identifier)) {
  2042. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  2043. << "redefine_extname";
  2044. return;
  2045. }
  2046. Token AliasName = Tok;
  2047. PP.Lex(Tok);
  2048. if (Tok.isNot(tok::eod)) {
  2049. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
  2050. "redefine_extname";
  2051. return;
  2052. }
  2053. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
  2054. 3);
  2055. Token &pragmaRedefTok = Toks[0];
  2056. pragmaRedefTok.startToken();
  2057. pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
  2058. pragmaRedefTok.setLocation(RedefLoc);
  2059. pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
  2060. Toks[1] = RedefName;
  2061. Toks[2] = AliasName;
  2062. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2063. /*IsReinject=*/false);
  2064. }
  2065. void PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
  2066. PragmaIntroducer Introducer,
  2067. Token &Tok) {
  2068. tok::OnOffSwitch OOS;
  2069. if (PP.LexOnOffSwitch(OOS))
  2070. return;
  2071. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  2072. 1);
  2073. Toks[0].startToken();
  2074. Toks[0].setKind(tok::annot_pragma_fp_contract);
  2075. Toks[0].setLocation(Tok.getLocation());
  2076. Toks[0].setAnnotationEndLoc(Tok.getLocation());
  2077. Toks[0].setAnnotationValue(reinterpret_cast<void*>(
  2078. static_cast<uintptr_t>(OOS)));
  2079. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2080. /*IsReinject=*/false);
  2081. }
  2082. void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
  2083. PragmaIntroducer Introducer,
  2084. Token &Tok) {
  2085. PP.LexUnexpandedToken(Tok);
  2086. if (Tok.isNot(tok::identifier)) {
  2087. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
  2088. "OPENCL";
  2089. return;
  2090. }
  2091. IdentifierInfo *Ext = Tok.getIdentifierInfo();
  2092. SourceLocation NameLoc = Tok.getLocation();
  2093. PP.Lex(Tok);
  2094. if (Tok.isNot(tok::colon)) {
  2095. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
  2096. return;
  2097. }
  2098. PP.Lex(Tok);
  2099. if (Tok.isNot(tok::identifier)) {
  2100. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
  2101. return;
  2102. }
  2103. IdentifierInfo *Pred = Tok.getIdentifierInfo();
  2104. OpenCLExtState State;
  2105. if (Pred->isStr("enable")) {
  2106. State = Enable;
  2107. } else if (Pred->isStr("disable")) {
  2108. State = Disable;
  2109. } else if (Pred->isStr("begin"))
  2110. State = Begin;
  2111. else if (Pred->isStr("end"))
  2112. State = End;
  2113. else {
  2114. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
  2115. << Ext->isStr("all");
  2116. return;
  2117. }
  2118. SourceLocation StateLoc = Tok.getLocation();
  2119. PP.Lex(Tok);
  2120. if (Tok.isNot(tok::eod)) {
  2121. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
  2122. "OPENCL EXTENSION";
  2123. return;
  2124. }
  2125. auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
  2126. Info->first = Ext;
  2127. Info->second = State;
  2128. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  2129. 1);
  2130. Toks[0].startToken();
  2131. Toks[0].setKind(tok::annot_pragma_opencl_extension);
  2132. Toks[0].setLocation(NameLoc);
  2133. Toks[0].setAnnotationValue(static_cast<void*>(Info));
  2134. Toks[0].setAnnotationEndLoc(StateLoc);
  2135. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2136. /*IsReinject=*/false);
  2137. if (PP.getPPCallbacks())
  2138. PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
  2139. StateLoc, State);
  2140. }
  2141. /// Handle '#pragma omp ...' when OpenMP is disabled.
  2142. ///
  2143. void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
  2144. PragmaIntroducer Introducer,
  2145. Token &FirstTok) {
  2146. if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
  2147. FirstTok.getLocation())) {
  2148. PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
  2149. PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
  2150. diag::Severity::Ignored, SourceLocation());
  2151. }
  2152. PP.DiscardUntilEndOfDirective();
  2153. }
  2154. /// Handle '#pragma omp ...' when OpenMP is enabled.
  2155. ///
  2156. void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
  2157. PragmaIntroducer Introducer,
  2158. Token &FirstTok) {
  2159. SmallVector<Token, 16> Pragma;
  2160. Token Tok;
  2161. Tok.startToken();
  2162. Tok.setKind(tok::annot_pragma_openmp);
  2163. Tok.setLocation(Introducer.Loc);
  2164. while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
  2165. Pragma.push_back(Tok);
  2166. PP.Lex(Tok);
  2167. if (Tok.is(tok::annot_pragma_openmp)) {
  2168. PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
  2169. unsigned InnerPragmaCnt = 1;
  2170. while (InnerPragmaCnt != 0) {
  2171. PP.Lex(Tok);
  2172. if (Tok.is(tok::annot_pragma_openmp))
  2173. ++InnerPragmaCnt;
  2174. else if (Tok.is(tok::annot_pragma_openmp_end))
  2175. --InnerPragmaCnt;
  2176. }
  2177. PP.Lex(Tok);
  2178. }
  2179. }
  2180. SourceLocation EodLoc = Tok.getLocation();
  2181. Tok.startToken();
  2182. Tok.setKind(tok::annot_pragma_openmp_end);
  2183. Tok.setLocation(EodLoc);
  2184. Pragma.push_back(Tok);
  2185. auto Toks = std::make_unique<Token[]>(Pragma.size());
  2186. std::copy(Pragma.begin(), Pragma.end(), Toks.get());
  2187. PP.EnterTokenStream(std::move(Toks), Pragma.size(),
  2188. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  2189. }
  2190. /// Handle '#pragma pointers_to_members'
  2191. // The grammar for this pragma is as follows:
  2192. //
  2193. // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
  2194. //
  2195. // #pragma pointers_to_members '(' 'best_case' ')'
  2196. // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
  2197. // #pragma pointers_to_members '(' inheritance-model ')'
  2198. void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
  2199. PragmaIntroducer Introducer,
  2200. Token &Tok) {
  2201. SourceLocation PointersToMembersLoc = Tok.getLocation();
  2202. PP.Lex(Tok);
  2203. if (Tok.isNot(tok::l_paren)) {
  2204. PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
  2205. << "pointers_to_members";
  2206. return;
  2207. }
  2208. PP.Lex(Tok);
  2209. const IdentifierInfo *Arg = Tok.getIdentifierInfo();
  2210. if (!Arg) {
  2211. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  2212. << "pointers_to_members";
  2213. return;
  2214. }
  2215. PP.Lex(Tok);
  2216. LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
  2217. if (Arg->isStr("best_case")) {
  2218. RepresentationMethod = LangOptions::PPTMK_BestCase;
  2219. } else {
  2220. if (Arg->isStr("full_generality")) {
  2221. if (Tok.is(tok::comma)) {
  2222. PP.Lex(Tok);
  2223. Arg = Tok.getIdentifierInfo();
  2224. if (!Arg) {
  2225. PP.Diag(Tok.getLocation(),
  2226. diag::err_pragma_pointers_to_members_unknown_kind)
  2227. << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
  2228. return;
  2229. }
  2230. PP.Lex(Tok);
  2231. } else if (Tok.is(tok::r_paren)) {
  2232. // #pragma pointers_to_members(full_generality) implicitly specifies
  2233. // virtual_inheritance.
  2234. Arg = nullptr;
  2235. RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
  2236. } else {
  2237. PP.Diag(Tok.getLocation(), diag::err_expected_punc)
  2238. << "full_generality";
  2239. return;
  2240. }
  2241. }
  2242. if (Arg) {
  2243. if (Arg->isStr("single_inheritance")) {
  2244. RepresentationMethod =
  2245. LangOptions::PPTMK_FullGeneralitySingleInheritance;
  2246. } else if (Arg->isStr("multiple_inheritance")) {
  2247. RepresentationMethod =
  2248. LangOptions::PPTMK_FullGeneralityMultipleInheritance;
  2249. } else if (Arg->isStr("virtual_inheritance")) {
  2250. RepresentationMethod =
  2251. LangOptions::PPTMK_FullGeneralityVirtualInheritance;
  2252. } else {
  2253. PP.Diag(Tok.getLocation(),
  2254. diag::err_pragma_pointers_to_members_unknown_kind)
  2255. << Arg << /*HasPointerDeclaration*/ 1;
  2256. return;
  2257. }
  2258. }
  2259. }
  2260. if (Tok.isNot(tok::r_paren)) {
  2261. PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
  2262. << (Arg ? Arg->getName() : "full_generality");
  2263. return;
  2264. }
  2265. SourceLocation EndLoc = Tok.getLocation();
  2266. PP.Lex(Tok);
  2267. if (Tok.isNot(tok::eod)) {
  2268. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  2269. << "pointers_to_members";
  2270. return;
  2271. }
  2272. Token AnnotTok;
  2273. AnnotTok.startToken();
  2274. AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
  2275. AnnotTok.setLocation(PointersToMembersLoc);
  2276. AnnotTok.setAnnotationEndLoc(EndLoc);
  2277. AnnotTok.setAnnotationValue(
  2278. reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
  2279. PP.EnterToken(AnnotTok, /*IsReinject=*/true);
  2280. }
  2281. /// Handle '#pragma vtordisp'
  2282. // The grammar for this pragma is as follows:
  2283. //
  2284. // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
  2285. //
  2286. // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
  2287. // #pragma vtordisp '(' 'pop' ')'
  2288. // #pragma vtordisp '(' ')'
  2289. void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
  2290. PragmaIntroducer Introducer, Token &Tok) {
  2291. SourceLocation VtorDispLoc = Tok.getLocation();
  2292. PP.Lex(Tok);
  2293. if (Tok.isNot(tok::l_paren)) {
  2294. PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
  2295. return;
  2296. }
  2297. PP.Lex(Tok);
  2298. Sema::PragmaMsStackAction Action = Sema::PSK_Set;
  2299. const IdentifierInfo *II = Tok.getIdentifierInfo();
  2300. if (II) {
  2301. if (II->isStr("push")) {
  2302. // #pragma vtordisp(push, mode)
  2303. PP.Lex(Tok);
  2304. if (Tok.isNot(tok::comma)) {
  2305. PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
  2306. return;
  2307. }
  2308. PP.Lex(Tok);
  2309. Action = Sema::PSK_Push_Set;
  2310. // not push, could be on/off
  2311. } else if (II->isStr("pop")) {
  2312. // #pragma vtordisp(pop)
  2313. PP.Lex(Tok);
  2314. Action = Sema::PSK_Pop;
  2315. }
  2316. // not push or pop, could be on/off
  2317. } else {
  2318. if (Tok.is(tok::r_paren)) {
  2319. // #pragma vtordisp()
  2320. Action = Sema::PSK_Reset;
  2321. }
  2322. }
  2323. uint64_t Value = 0;
  2324. if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
  2325. const IdentifierInfo *II = Tok.getIdentifierInfo();
  2326. if (II && II->isStr("off")) {
  2327. PP.Lex(Tok);
  2328. Value = 0;
  2329. } else if (II && II->isStr("on")) {
  2330. PP.Lex(Tok);
  2331. Value = 1;
  2332. } else if (Tok.is(tok::numeric_constant) &&
  2333. PP.parseSimpleIntegerLiteral(Tok, Value)) {
  2334. if (Value > 2) {
  2335. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
  2336. << 0 << 2 << "vtordisp";
  2337. return;
  2338. }
  2339. } else {
  2340. PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
  2341. << "vtordisp";
  2342. return;
  2343. }
  2344. }
  2345. // Finish the pragma: ')' $
  2346. if (Tok.isNot(tok::r_paren)) {
  2347. PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
  2348. return;
  2349. }
  2350. SourceLocation EndLoc = Tok.getLocation();
  2351. PP.Lex(Tok);
  2352. if (Tok.isNot(tok::eod)) {
  2353. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  2354. << "vtordisp";
  2355. return;
  2356. }
  2357. // Enter the annotation.
  2358. Token AnnotTok;
  2359. AnnotTok.startToken();
  2360. AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
  2361. AnnotTok.setLocation(VtorDispLoc);
  2362. AnnotTok.setAnnotationEndLoc(EndLoc);
  2363. AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
  2364. static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
  2365. PP.EnterToken(AnnotTok, /*IsReinject=*/false);
  2366. }
  2367. /// Handle all MS pragmas. Simply forwards the tokens after inserting
  2368. /// an annotation token.
  2369. void PragmaMSPragma::HandlePragma(Preprocessor &PP,
  2370. PragmaIntroducer Introducer, Token &Tok) {
  2371. Token EoF, AnnotTok;
  2372. EoF.startToken();
  2373. EoF.setKind(tok::eof);
  2374. AnnotTok.startToken();
  2375. AnnotTok.setKind(tok::annot_pragma_ms_pragma);
  2376. AnnotTok.setLocation(Tok.getLocation());
  2377. AnnotTok.setAnnotationEndLoc(Tok.getLocation());
  2378. SmallVector<Token, 8> TokenVector;
  2379. // Suck up all of the tokens before the eod.
  2380. for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
  2381. TokenVector.push_back(Tok);
  2382. AnnotTok.setAnnotationEndLoc(Tok.getLocation());
  2383. }
  2384. // Add a sentinel EoF token to the end of the list.
  2385. TokenVector.push_back(EoF);
  2386. // We must allocate this array with new because EnterTokenStream is going to
  2387. // delete it later.
  2388. markAsReinjectedForRelexing(TokenVector);
  2389. auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
  2390. std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
  2391. auto Value = new (PP.getPreprocessorAllocator())
  2392. std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
  2393. TokenVector.size());
  2394. AnnotTok.setAnnotationValue(Value);
  2395. PP.EnterToken(AnnotTok, /*IsReinject*/ false);
  2396. }
  2397. /// Handle the \#pragma float_control extension.
  2398. ///
  2399. /// The syntax is:
  2400. /// \code
  2401. /// #pragma float_control(keyword[, setting] [,push])
  2402. /// \endcode
  2403. /// Where 'keyword' and 'setting' are identifiers.
  2404. // 'keyword' can be: precise, except, push, pop
  2405. // 'setting' can be: on, off
  2406. /// The optional arguments 'setting' and 'push' are supported only
  2407. /// when the keyword is 'precise' or 'except'.
  2408. void PragmaFloatControlHandler::HandlePragma(Preprocessor &PP,
  2409. PragmaIntroducer Introducer,
  2410. Token &Tok) {
  2411. Sema::PragmaMsStackAction Action = Sema::PSK_Set;
  2412. SourceLocation FloatControlLoc = Tok.getLocation();
  2413. Token PragmaName = Tok;
  2414. if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) {
  2415. PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
  2416. << PragmaName.getIdentifierInfo()->getName();
  2417. return;
  2418. }
  2419. PP.Lex(Tok);
  2420. if (Tok.isNot(tok::l_paren)) {
  2421. PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren;
  2422. return;
  2423. }
  2424. // Read the identifier.
  2425. PP.Lex(Tok);
  2426. if (Tok.isNot(tok::identifier)) {
  2427. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2428. return;
  2429. }
  2430. // Verify that this is one of the float control options.
  2431. IdentifierInfo *II = Tok.getIdentifierInfo();
  2432. PragmaFloatControlKind Kind =
  2433. llvm::StringSwitch<PragmaFloatControlKind>(II->getName())
  2434. .Case("precise", PFC_Precise)
  2435. .Case("except", PFC_Except)
  2436. .Case("push", PFC_Push)
  2437. .Case("pop", PFC_Pop)
  2438. .Default(PFC_Unknown);
  2439. PP.Lex(Tok); // the identifier
  2440. if (Kind == PFC_Unknown) {
  2441. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2442. return;
  2443. } else if (Kind == PFC_Push || Kind == PFC_Pop) {
  2444. if (Tok.isNot(tok::r_paren)) {
  2445. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2446. return;
  2447. }
  2448. PP.Lex(Tok); // Eat the r_paren
  2449. Action = (Kind == PFC_Pop) ? Sema::PSK_Pop : Sema::PSK_Push;
  2450. } else {
  2451. if (Tok.is(tok::r_paren))
  2452. // Selecting Precise or Except
  2453. PP.Lex(Tok); // the r_paren
  2454. else if (Tok.isNot(tok::comma)) {
  2455. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2456. return;
  2457. } else {
  2458. PP.Lex(Tok); // ,
  2459. if (!Tok.isAnyIdentifier()) {
  2460. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2461. return;
  2462. }
  2463. StringRef PushOnOff = Tok.getIdentifierInfo()->getName();
  2464. if (PushOnOff == "on")
  2465. // Kind is set correctly
  2466. ;
  2467. else if (PushOnOff == "off") {
  2468. if (Kind == PFC_Precise)
  2469. Kind = PFC_NoPrecise;
  2470. if (Kind == PFC_Except)
  2471. Kind = PFC_NoExcept;
  2472. } else if (PushOnOff == "push") {
  2473. Action = Sema::PSK_Push_Set;
  2474. } else {
  2475. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2476. return;
  2477. }
  2478. PP.Lex(Tok); // the identifier
  2479. if (Tok.is(tok::comma)) {
  2480. PP.Lex(Tok); // ,
  2481. if (!Tok.isAnyIdentifier()) {
  2482. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2483. return;
  2484. }
  2485. StringRef ExpectedPush = Tok.getIdentifierInfo()->getName();
  2486. if (ExpectedPush == "push") {
  2487. Action = Sema::PSK_Push_Set;
  2488. } else {
  2489. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2490. return;
  2491. }
  2492. PP.Lex(Tok); // the push identifier
  2493. }
  2494. if (Tok.isNot(tok::r_paren)) {
  2495. PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
  2496. return;
  2497. }
  2498. PP.Lex(Tok); // the r_paren
  2499. }
  2500. }
  2501. SourceLocation EndLoc = Tok.getLocation();
  2502. if (Tok.isNot(tok::eod)) {
  2503. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  2504. << "float_control";
  2505. return;
  2506. }
  2507. // Note: there is no accomodation for PP callback for this pragma.
  2508. // Enter the annotation.
  2509. auto TokenArray = std::make_unique<Token[]>(1);
  2510. TokenArray[0].startToken();
  2511. TokenArray[0].setKind(tok::annot_pragma_float_control);
  2512. TokenArray[0].setLocation(FloatControlLoc);
  2513. TokenArray[0].setAnnotationEndLoc(EndLoc);
  2514. // Create an encoding of Action and Value by shifting the Action into
  2515. // the high 16 bits then union with the Kind.
  2516. TokenArray[0].setAnnotationValue(reinterpret_cast<void *>(
  2517. static_cast<uintptr_t>((Action << 16) | (Kind & 0xFFFF))));
  2518. PP.EnterTokenStream(std::move(TokenArray), 1,
  2519. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  2520. }
  2521. /// Handle the Microsoft \#pragma detect_mismatch extension.
  2522. ///
  2523. /// The syntax is:
  2524. /// \code
  2525. /// #pragma detect_mismatch("name", "value")
  2526. /// \endcode
  2527. /// Where 'name' and 'value' are quoted strings. The values are embedded in
  2528. /// the object file and passed along to the linker. If the linker detects a
  2529. /// mismatch in the object file's values for the given name, a LNK2038 error
  2530. /// is emitted. See MSDN for more details.
  2531. void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
  2532. PragmaIntroducer Introducer,
  2533. Token &Tok) {
  2534. SourceLocation DetectMismatchLoc = Tok.getLocation();
  2535. PP.Lex(Tok);
  2536. if (Tok.isNot(tok::l_paren)) {
  2537. PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
  2538. return;
  2539. }
  2540. // Read the name to embed, which must be a string literal.
  2541. std::string NameString;
  2542. if (!PP.LexStringLiteral(Tok, NameString,
  2543. "pragma detect_mismatch",
  2544. /*AllowMacroExpansion=*/true))
  2545. return;
  2546. // Read the comma followed by a second string literal.
  2547. std::string ValueString;
  2548. if (Tok.isNot(tok::comma)) {
  2549. PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
  2550. return;
  2551. }
  2552. if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
  2553. /*AllowMacroExpansion=*/true))
  2554. return;
  2555. if (Tok.isNot(tok::r_paren)) {
  2556. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
  2557. return;
  2558. }
  2559. PP.Lex(Tok); // Eat the r_paren.
  2560. if (Tok.isNot(tok::eod)) {
  2561. PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
  2562. return;
  2563. }
  2564. // If the pragma is lexically sound, notify any interested PPCallbacks.
  2565. if (PP.getPPCallbacks())
  2566. PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
  2567. ValueString);
  2568. Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
  2569. }
  2570. /// Handle the microsoft \#pragma comment extension.
  2571. ///
  2572. /// The syntax is:
  2573. /// \code
  2574. /// #pragma comment(linker, "foo")
  2575. /// \endcode
  2576. /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
  2577. /// "foo" is a string, which is fully macro expanded, and permits string
  2578. /// concatenation, embedded escape characters etc. See MSDN for more details.
  2579. void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
  2580. PragmaIntroducer Introducer,
  2581. Token &Tok) {
  2582. SourceLocation CommentLoc = Tok.getLocation();
  2583. PP.Lex(Tok);
  2584. if (Tok.isNot(tok::l_paren)) {
  2585. PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
  2586. return;
  2587. }
  2588. // Read the identifier.
  2589. PP.Lex(Tok);
  2590. if (Tok.isNot(tok::identifier)) {
  2591. PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
  2592. return;
  2593. }
  2594. // Verify that this is one of the 5 explicitly listed options.
  2595. IdentifierInfo *II = Tok.getIdentifierInfo();
  2596. PragmaMSCommentKind Kind =
  2597. llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
  2598. .Case("linker", PCK_Linker)
  2599. .Case("lib", PCK_Lib)
  2600. .Case("compiler", PCK_Compiler)
  2601. .Case("exestr", PCK_ExeStr)
  2602. .Case("user", PCK_User)
  2603. .Default(PCK_Unknown);
  2604. if (Kind == PCK_Unknown) {
  2605. PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
  2606. return;
  2607. }
  2608. if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
  2609. PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
  2610. << II->getName();
  2611. return;
  2612. }
  2613. // On PS4, issue a warning about any pragma comments other than
  2614. // #pragma comment lib.
  2615. if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
  2616. PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
  2617. << II->getName();
  2618. return;
  2619. }
  2620. // Read the optional string if present.
  2621. PP.Lex(Tok);
  2622. std::string ArgumentString;
  2623. if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
  2624. "pragma comment",
  2625. /*AllowMacroExpansion=*/true))
  2626. return;
  2627. // FIXME: warn that 'exestr' is deprecated.
  2628. // FIXME: If the kind is "compiler" warn if the string is present (it is
  2629. // ignored).
  2630. // The MSDN docs say that "lib" and "linker" require a string and have a short
  2631. // list of linker options they support, but in practice MSVC doesn't
  2632. // issue a diagnostic. Therefore neither does clang.
  2633. if (Tok.isNot(tok::r_paren)) {
  2634. PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
  2635. return;
  2636. }
  2637. PP.Lex(Tok); // eat the r_paren.
  2638. if (Tok.isNot(tok::eod)) {
  2639. PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
  2640. return;
  2641. }
  2642. // If the pragma is lexically sound, notify any interested PPCallbacks.
  2643. if (PP.getPPCallbacks())
  2644. PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
  2645. Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
  2646. }
  2647. // #pragma clang optimize off
  2648. // #pragma clang optimize on
  2649. void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
  2650. PragmaIntroducer Introducer,
  2651. Token &FirstToken) {
  2652. Token Tok;
  2653. PP.Lex(Tok);
  2654. if (Tok.is(tok::eod)) {
  2655. PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
  2656. << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
  2657. return;
  2658. }
  2659. if (Tok.isNot(tok::identifier)) {
  2660. PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
  2661. << PP.getSpelling(Tok);
  2662. return;
  2663. }
  2664. const IdentifierInfo *II = Tok.getIdentifierInfo();
  2665. // The only accepted values are 'on' or 'off'.
  2666. bool IsOn = false;
  2667. if (II->isStr("on")) {
  2668. IsOn = true;
  2669. } else if (!II->isStr("off")) {
  2670. PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
  2671. << PP.getSpelling(Tok);
  2672. return;
  2673. }
  2674. PP.Lex(Tok);
  2675. if (Tok.isNot(tok::eod)) {
  2676. PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
  2677. << PP.getSpelling(Tok);
  2678. return;
  2679. }
  2680. Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
  2681. }
  2682. namespace {
  2683. /// Used as the annotation value for tok::annot_pragma_fp.
  2684. struct TokFPAnnotValue {
  2685. enum FlagKinds { Contract, Reassociate, Exceptions };
  2686. enum FlagValues { On, Off, Fast };
  2687. llvm::Optional<LangOptions::FPModeKind> ContractValue;
  2688. llvm::Optional<LangOptions::FPModeKind> ReassociateValue;
  2689. llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
  2690. };
  2691. } // end anonymous namespace
  2692. void PragmaFPHandler::HandlePragma(Preprocessor &PP,
  2693. PragmaIntroducer Introducer, Token &Tok) {
  2694. // fp
  2695. Token PragmaName = Tok;
  2696. SmallVector<Token, 1> TokenList;
  2697. PP.Lex(Tok);
  2698. if (Tok.isNot(tok::identifier)) {
  2699. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
  2700. << /*MissingOption=*/true << "";
  2701. return;
  2702. }
  2703. auto *AnnotValue = new (PP.getPreprocessorAllocator()) TokFPAnnotValue;
  2704. while (Tok.is(tok::identifier)) {
  2705. IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
  2706. auto FlagKind =
  2707. llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
  2708. OptionInfo->getName())
  2709. .Case("contract", TokFPAnnotValue::Contract)
  2710. .Case("reassociate", TokFPAnnotValue::Reassociate)
  2711. .Case("exceptions", TokFPAnnotValue::Exceptions)
  2712. .Default(None);
  2713. if (!FlagKind) {
  2714. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
  2715. << /*MissingOption=*/false << OptionInfo;
  2716. return;
  2717. }
  2718. PP.Lex(Tok);
  2719. // Read '('
  2720. if (Tok.isNot(tok::l_paren)) {
  2721. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
  2722. return;
  2723. }
  2724. PP.Lex(Tok);
  2725. if (Tok.isNot(tok::identifier)) {
  2726. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
  2727. << PP.getSpelling(Tok) << OptionInfo->getName()
  2728. << static_cast<int>(*FlagKind);
  2729. return;
  2730. }
  2731. const IdentifierInfo *II = Tok.getIdentifierInfo();
  2732. if (FlagKind == TokFPAnnotValue::Contract) {
  2733. AnnotValue->ContractValue =
  2734. llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>(
  2735. II->getName())
  2736. .Case("on", LangOptions::FPModeKind::FPM_On)
  2737. .Case("off", LangOptions::FPModeKind::FPM_Off)
  2738. .Case("fast", LangOptions::FPModeKind::FPM_Fast)
  2739. .Default(llvm::None);
  2740. if (!AnnotValue->ContractValue) {
  2741. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
  2742. << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
  2743. return;
  2744. }
  2745. } else if (FlagKind == TokFPAnnotValue::Reassociate) {
  2746. AnnotValue->ReassociateValue =
  2747. llvm::StringSwitch<llvm::Optional<LangOptions::FPModeKind>>(
  2748. II->getName())
  2749. .Case("on", LangOptions::FPModeKind::FPM_On)
  2750. .Case("off", LangOptions::FPModeKind::FPM_Off)
  2751. .Default(llvm::None);
  2752. if (!AnnotValue->ReassociateValue) {
  2753. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
  2754. << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
  2755. return;
  2756. }
  2757. } else if (FlagKind == TokFPAnnotValue::Exceptions) {
  2758. AnnotValue->ExceptionsValue =
  2759. llvm::StringSwitch<llvm::Optional<LangOptions::FPExceptionModeKind>>(
  2760. II->getName())
  2761. .Case("ignore", LangOptions::FPE_Ignore)
  2762. .Case("maytrap", LangOptions::FPE_MayTrap)
  2763. .Case("strict", LangOptions::FPE_Strict)
  2764. .Default(llvm::None);
  2765. if (!AnnotValue->ExceptionsValue) {
  2766. PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
  2767. << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
  2768. return;
  2769. }
  2770. }
  2771. PP.Lex(Tok);
  2772. // Read ')'
  2773. if (Tok.isNot(tok::r_paren)) {
  2774. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
  2775. return;
  2776. }
  2777. PP.Lex(Tok);
  2778. }
  2779. if (Tok.isNot(tok::eod)) {
  2780. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  2781. << "clang fp";
  2782. return;
  2783. }
  2784. Token FPTok;
  2785. FPTok.startToken();
  2786. FPTok.setKind(tok::annot_pragma_fp);
  2787. FPTok.setLocation(PragmaName.getLocation());
  2788. FPTok.setAnnotationEndLoc(PragmaName.getLocation());
  2789. FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
  2790. TokenList.push_back(FPTok);
  2791. auto TokenArray = std::make_unique<Token[]>(TokenList.size());
  2792. std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
  2793. PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
  2794. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  2795. }
  2796. void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(Preprocessor &PP,
  2797. PragmaIntroducer Introducer,
  2798. Token &Tok) {
  2799. Token PragmaName = Tok;
  2800. SmallVector<Token, 1> TokenList;
  2801. if (!PP.getTargetInfo().hasStrictFP() && !PP.getLangOpts().ExpStrictFP) {
  2802. PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
  2803. << PragmaName.getIdentifierInfo()->getName();
  2804. return;
  2805. }
  2806. PP.Lex(Tok);
  2807. if (Tok.isNot(tok::identifier)) {
  2808. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
  2809. << PragmaName.getIdentifierInfo()->getName();
  2810. return;
  2811. }
  2812. IdentifierInfo *II = Tok.getIdentifierInfo();
  2813. auto RM =
  2814. llvm::StringSwitch<llvm::RoundingMode>(II->getName())
  2815. .Case("FE_TOWARDZERO", llvm::RoundingMode::TowardZero)
  2816. .Case("FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven)
  2817. .Case("FE_UPWARD", llvm::RoundingMode::TowardPositive)
  2818. .Case("FE_DOWNWARD", llvm::RoundingMode::TowardNegative)
  2819. .Case("FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway)
  2820. .Case("FE_DYNAMIC", llvm::RoundingMode::Dynamic)
  2821. .Default(llvm::RoundingMode::Invalid);
  2822. if (RM == llvm::RoundingMode::Invalid) {
  2823. PP.Diag(Tok.getLocation(), diag::warn_stdc_unknown_rounding_mode);
  2824. return;
  2825. }
  2826. PP.Lex(Tok);
  2827. if (Tok.isNot(tok::eod)) {
  2828. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  2829. << "STDC FENV_ROUND";
  2830. return;
  2831. }
  2832. // Until the pragma is fully implemented, issue a warning.
  2833. PP.Diag(Tok.getLocation(), diag::warn_stdc_fenv_round_not_supported);
  2834. MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
  2835. 1);
  2836. Toks[0].startToken();
  2837. Toks[0].setKind(tok::annot_pragma_fenv_round);
  2838. Toks[0].setLocation(Tok.getLocation());
  2839. Toks[0].setAnnotationEndLoc(Tok.getLocation());
  2840. Toks[0].setAnnotationValue(
  2841. reinterpret_cast<void *>(static_cast<uintptr_t>(RM)));
  2842. PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
  2843. /*IsReinject=*/false);
  2844. }
  2845. void Parser::HandlePragmaFP() {
  2846. assert(Tok.is(tok::annot_pragma_fp));
  2847. auto *AnnotValue =
  2848. reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
  2849. if (AnnotValue->ReassociateValue)
  2850. Actions.ActOnPragmaFPReassociate(Tok.getLocation(),
  2851. *AnnotValue->ReassociateValue ==
  2852. LangOptions::FPModeKind::FPM_On);
  2853. if (AnnotValue->ContractValue)
  2854. Actions.ActOnPragmaFPContract(Tok.getLocation(),
  2855. *AnnotValue->ContractValue);
  2856. if (AnnotValue->ExceptionsValue)
  2857. Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
  2858. *AnnotValue->ExceptionsValue);
  2859. ConsumeAnnotationToken();
  2860. }
  2861. /// Parses loop or unroll pragma hint value and fills in Info.
  2862. static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
  2863. Token Option, bool ValueInParens,
  2864. PragmaLoopHintInfo &Info) {
  2865. SmallVector<Token, 1> ValueList;
  2866. int OpenParens = ValueInParens ? 1 : 0;
  2867. // Read constant expression.
  2868. while (Tok.isNot(tok::eod)) {
  2869. if (Tok.is(tok::l_paren))
  2870. OpenParens++;
  2871. else if (Tok.is(tok::r_paren)) {
  2872. OpenParens--;
  2873. if (OpenParens == 0 && ValueInParens)
  2874. break;
  2875. }
  2876. ValueList.push_back(Tok);
  2877. PP.Lex(Tok);
  2878. }
  2879. if (ValueInParens) {
  2880. // Read ')'
  2881. if (Tok.isNot(tok::r_paren)) {
  2882. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
  2883. return true;
  2884. }
  2885. PP.Lex(Tok);
  2886. }
  2887. Token EOFTok;
  2888. EOFTok.startToken();
  2889. EOFTok.setKind(tok::eof);
  2890. EOFTok.setLocation(Tok.getLocation());
  2891. ValueList.push_back(EOFTok); // Terminates expression for parsing.
  2892. markAsReinjectedForRelexing(ValueList);
  2893. Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
  2894. Info.PragmaName = PragmaName;
  2895. Info.Option = Option;
  2896. return false;
  2897. }
  2898. /// Handle the \#pragma clang loop directive.
  2899. /// #pragma clang 'loop' loop-hints
  2900. ///
  2901. /// loop-hints:
  2902. /// loop-hint loop-hints[opt]
  2903. ///
  2904. /// loop-hint:
  2905. /// 'vectorize' '(' loop-hint-keyword ')'
  2906. /// 'interleave' '(' loop-hint-keyword ')'
  2907. /// 'unroll' '(' unroll-hint-keyword ')'
  2908. /// 'vectorize_predicate' '(' loop-hint-keyword ')'
  2909. /// 'vectorize_width' '(' loop-hint-value ')'
  2910. /// 'interleave_count' '(' loop-hint-value ')'
  2911. /// 'unroll_count' '(' loop-hint-value ')'
  2912. /// 'pipeline' '(' disable ')'
  2913. /// 'pipeline_initiation_interval' '(' loop-hint-value ')'
  2914. ///
  2915. /// loop-hint-keyword:
  2916. /// 'enable'
  2917. /// 'disable'
  2918. /// 'assume_safety'
  2919. ///
  2920. /// unroll-hint-keyword:
  2921. /// 'enable'
  2922. /// 'disable'
  2923. /// 'full'
  2924. ///
  2925. /// loop-hint-value:
  2926. /// constant-expression
  2927. ///
  2928. /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
  2929. /// try vectorizing the instructions of the loop it precedes. Specifying
  2930. /// interleave(enable) or interleave_count(_value_) instructs llvm to try
  2931. /// interleaving multiple iterations of the loop it precedes. The width of the
  2932. /// vector instructions is specified by vectorize_width() and the number of
  2933. /// interleaved loop iterations is specified by interleave_count(). Specifying a
  2934. /// value of 1 effectively disables vectorization/interleaving, even if it is
  2935. /// possible and profitable, and 0 is invalid. The loop vectorizer currently
  2936. /// only works on inner loops.
  2937. ///
  2938. /// The unroll and unroll_count directives control the concatenation
  2939. /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
  2940. /// completely if the trip count is known at compile time and unroll partially
  2941. /// if the trip count is not known. Specifying unroll(full) is similar to
  2942. /// unroll(enable) but will unroll the loop only if the trip count is known at
  2943. /// compile time. Specifying unroll(disable) disables unrolling for the
  2944. /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
  2945. /// loop the number of times indicated by the value.
  2946. void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
  2947. PragmaIntroducer Introducer,
  2948. Token &Tok) {
  2949. // Incoming token is "loop" from "#pragma clang loop".
  2950. Token PragmaName = Tok;
  2951. SmallVector<Token, 1> TokenList;
  2952. // Lex the optimization option and verify it is an identifier.
  2953. PP.Lex(Tok);
  2954. if (Tok.isNot(tok::identifier)) {
  2955. PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
  2956. << /*MissingOption=*/true << "";
  2957. return;
  2958. }
  2959. while (Tok.is(tok::identifier)) {
  2960. Token Option = Tok;
  2961. IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
  2962. bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
  2963. .Case("vectorize", true)
  2964. .Case("interleave", true)
  2965. .Case("unroll", true)
  2966. .Case("distribute", true)
  2967. .Case("vectorize_predicate", true)
  2968. .Case("vectorize_width", true)
  2969. .Case("interleave_count", true)
  2970. .Case("unroll_count", true)
  2971. .Case("pipeline", true)
  2972. .Case("pipeline_initiation_interval", true)
  2973. .Default(false);
  2974. if (!OptionValid) {
  2975. PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
  2976. << /*MissingOption=*/false << OptionInfo;
  2977. return;
  2978. }
  2979. PP.Lex(Tok);
  2980. // Read '('
  2981. if (Tok.isNot(tok::l_paren)) {
  2982. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
  2983. return;
  2984. }
  2985. PP.Lex(Tok);
  2986. auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
  2987. if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
  2988. *Info))
  2989. return;
  2990. // Generate the loop hint token.
  2991. Token LoopHintTok;
  2992. LoopHintTok.startToken();
  2993. LoopHintTok.setKind(tok::annot_pragma_loop_hint);
  2994. LoopHintTok.setLocation(Introducer.Loc);
  2995. LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
  2996. LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
  2997. TokenList.push_back(LoopHintTok);
  2998. }
  2999. if (Tok.isNot(tok::eod)) {
  3000. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3001. << "clang loop";
  3002. return;
  3003. }
  3004. auto TokenArray = std::make_unique<Token[]>(TokenList.size());
  3005. std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
  3006. PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
  3007. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  3008. }
  3009. /// Handle the loop unroll optimization pragmas.
  3010. /// #pragma unroll
  3011. /// #pragma unroll unroll-hint-value
  3012. /// #pragma unroll '(' unroll-hint-value ')'
  3013. /// #pragma nounroll
  3014. /// #pragma unroll_and_jam
  3015. /// #pragma unroll_and_jam unroll-hint-value
  3016. /// #pragma unroll_and_jam '(' unroll-hint-value ')'
  3017. /// #pragma nounroll_and_jam
  3018. ///
  3019. /// unroll-hint-value:
  3020. /// constant-expression
  3021. ///
  3022. /// Loop unrolling hints can be specified with '#pragma unroll' or
  3023. /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
  3024. /// contained in parentheses. With no argument the directive instructs llvm to
  3025. /// try to unroll the loop completely. A positive integer argument can be
  3026. /// specified to indicate the number of times the loop should be unrolled. To
  3027. /// maximize compatibility with other compilers the unroll count argument can be
  3028. /// specified with or without parentheses. Specifying, '#pragma nounroll'
  3029. /// disables unrolling of the loop.
  3030. void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
  3031. PragmaIntroducer Introducer,
  3032. Token &Tok) {
  3033. // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
  3034. // "#pragma nounroll".
  3035. Token PragmaName = Tok;
  3036. PP.Lex(Tok);
  3037. auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
  3038. if (Tok.is(tok::eod)) {
  3039. // nounroll or unroll pragma without an argument.
  3040. Info->PragmaName = PragmaName;
  3041. Info->Option.startToken();
  3042. } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" ||
  3043. PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam") {
  3044. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3045. << PragmaName.getIdentifierInfo()->getName();
  3046. return;
  3047. } else {
  3048. // Unroll pragma with an argument: "#pragma unroll N" or
  3049. // "#pragma unroll(N)".
  3050. // Read '(' if it exists.
  3051. bool ValueInParens = Tok.is(tok::l_paren);
  3052. if (ValueInParens)
  3053. PP.Lex(Tok);
  3054. Token Option;
  3055. Option.startToken();
  3056. if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
  3057. return;
  3058. // In CUDA, the argument to '#pragma unroll' should not be contained in
  3059. // parentheses.
  3060. if (PP.getLangOpts().CUDA && ValueInParens)
  3061. PP.Diag(Info->Toks[0].getLocation(),
  3062. diag::warn_pragma_unroll_cuda_value_in_parens);
  3063. if (Tok.isNot(tok::eod)) {
  3064. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3065. << "unroll";
  3066. return;
  3067. }
  3068. }
  3069. // Generate the hint token.
  3070. auto TokenArray = std::make_unique<Token[]>(1);
  3071. TokenArray[0].startToken();
  3072. TokenArray[0].setKind(tok::annot_pragma_loop_hint);
  3073. TokenArray[0].setLocation(Introducer.Loc);
  3074. TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
  3075. TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
  3076. PP.EnterTokenStream(std::move(TokenArray), 1,
  3077. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  3078. }
  3079. /// Handle the Microsoft \#pragma intrinsic extension.
  3080. ///
  3081. /// The syntax is:
  3082. /// \code
  3083. /// #pragma intrinsic(memset)
  3084. /// #pragma intrinsic(strlen, memcpy)
  3085. /// \endcode
  3086. ///
  3087. /// Pragma intrisic tells the compiler to use a builtin version of the
  3088. /// function. Clang does it anyway, so the pragma doesn't really do anything.
  3089. /// Anyway, we emit a warning if the function specified in \#pragma intrinsic
  3090. /// isn't an intrinsic in clang and suggest to include intrin.h.
  3091. void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
  3092. PragmaIntroducer Introducer,
  3093. Token &Tok) {
  3094. PP.Lex(Tok);
  3095. if (Tok.isNot(tok::l_paren)) {
  3096. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
  3097. << "intrinsic";
  3098. return;
  3099. }
  3100. PP.Lex(Tok);
  3101. bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
  3102. while (Tok.is(tok::identifier)) {
  3103. IdentifierInfo *II = Tok.getIdentifierInfo();
  3104. if (!II->getBuiltinID())
  3105. PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
  3106. << II << SuggestIntrinH;
  3107. PP.Lex(Tok);
  3108. if (Tok.isNot(tok::comma))
  3109. break;
  3110. PP.Lex(Tok);
  3111. }
  3112. if (Tok.isNot(tok::r_paren)) {
  3113. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
  3114. << "intrinsic";
  3115. return;
  3116. }
  3117. PP.Lex(Tok);
  3118. if (Tok.isNot(tok::eod))
  3119. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3120. << "intrinsic";
  3121. }
  3122. // #pragma optimize("gsty", on|off)
  3123. void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
  3124. PragmaIntroducer Introducer,
  3125. Token &Tok) {
  3126. SourceLocation StartLoc = Tok.getLocation();
  3127. PP.Lex(Tok);
  3128. if (Tok.isNot(tok::l_paren)) {
  3129. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
  3130. return;
  3131. }
  3132. PP.Lex(Tok);
  3133. if (Tok.isNot(tok::string_literal)) {
  3134. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
  3135. return;
  3136. }
  3137. // We could syntax check the string but it's probably not worth the effort.
  3138. PP.Lex(Tok);
  3139. if (Tok.isNot(tok::comma)) {
  3140. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
  3141. return;
  3142. }
  3143. PP.Lex(Tok);
  3144. if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
  3145. PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
  3146. << "optimize" << /*Expected=*/true << "'on' or 'off'";
  3147. return;
  3148. }
  3149. IdentifierInfo *II = Tok.getIdentifierInfo();
  3150. if (!II || (!II->isStr("on") && !II->isStr("off"))) {
  3151. PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
  3152. << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
  3153. << "'on' or 'off'";
  3154. return;
  3155. }
  3156. PP.Lex(Tok);
  3157. if (Tok.isNot(tok::r_paren)) {
  3158. PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
  3159. return;
  3160. }
  3161. PP.Lex(Tok);
  3162. if (Tok.isNot(tok::eod)) {
  3163. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3164. << "optimize";
  3165. return;
  3166. }
  3167. PP.Diag(StartLoc, diag::warn_pragma_optimize);
  3168. }
  3169. void PragmaForceCUDAHostDeviceHandler::HandlePragma(
  3170. Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) {
  3171. Token FirstTok = Tok;
  3172. PP.Lex(Tok);
  3173. IdentifierInfo *Info = Tok.getIdentifierInfo();
  3174. if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
  3175. PP.Diag(FirstTok.getLocation(),
  3176. diag::warn_pragma_force_cuda_host_device_bad_arg);
  3177. return;
  3178. }
  3179. if (Info->isStr("begin"))
  3180. Actions.PushForceCUDAHostDevice();
  3181. else if (!Actions.PopForceCUDAHostDevice())
  3182. PP.Diag(FirstTok.getLocation(),
  3183. diag::err_pragma_cannot_end_force_cuda_host_device);
  3184. PP.Lex(Tok);
  3185. if (!Tok.is(tok::eod))
  3186. PP.Diag(FirstTok.getLocation(),
  3187. diag::warn_pragma_force_cuda_host_device_bad_arg);
  3188. }
  3189. /// Handle the #pragma clang attribute directive.
  3190. ///
  3191. /// The syntax is:
  3192. /// \code
  3193. /// #pragma clang attribute push (attribute, subject-set)
  3194. /// #pragma clang attribute push
  3195. /// #pragma clang attribute (attribute, subject-set)
  3196. /// #pragma clang attribute pop
  3197. /// \endcode
  3198. ///
  3199. /// There are also 'namespace' variants of push and pop directives. The bare
  3200. /// '#pragma clang attribute (attribute, subject-set)' version doesn't require a
  3201. /// namespace, since it always applies attributes to the most recently pushed
  3202. /// group, regardless of namespace.
  3203. /// \code
  3204. /// #pragma clang attribute namespace.push (attribute, subject-set)
  3205. /// #pragma clang attribute namespace.push
  3206. /// #pragma clang attribute namespace.pop
  3207. /// \endcode
  3208. ///
  3209. /// The subject-set clause defines the set of declarations which receive the
  3210. /// attribute. Its exact syntax is described in the LanguageExtensions document
  3211. /// in Clang's documentation.
  3212. ///
  3213. /// This directive instructs the compiler to begin/finish applying the specified
  3214. /// attribute to the set of attribute-specific declarations in the active range
  3215. /// of the pragma.
  3216. void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
  3217. PragmaIntroducer Introducer,
  3218. Token &FirstToken) {
  3219. Token Tok;
  3220. PP.Lex(Tok);
  3221. auto *Info = new (PP.getPreprocessorAllocator())
  3222. PragmaAttributeInfo(AttributesForPragmaAttribute);
  3223. // Parse the optional namespace followed by a period.
  3224. if (Tok.is(tok::identifier)) {
  3225. IdentifierInfo *II = Tok.getIdentifierInfo();
  3226. if (!II->isStr("push") && !II->isStr("pop")) {
  3227. Info->Namespace = II;
  3228. PP.Lex(Tok);
  3229. if (!Tok.is(tok::period)) {
  3230. PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
  3231. << II;
  3232. return;
  3233. }
  3234. PP.Lex(Tok);
  3235. }
  3236. }
  3237. if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
  3238. PP.Diag(Tok.getLocation(),
  3239. diag::err_pragma_attribute_expected_push_pop_paren);
  3240. return;
  3241. }
  3242. // Determine what action this pragma clang attribute represents.
  3243. if (Tok.is(tok::l_paren)) {
  3244. if (Info->Namespace) {
  3245. PP.Diag(Tok.getLocation(),
  3246. diag::err_pragma_attribute_namespace_on_attribute);
  3247. PP.Diag(Tok.getLocation(),
  3248. diag::note_pragma_attribute_namespace_on_attribute);
  3249. return;
  3250. }
  3251. Info->Action = PragmaAttributeInfo::Attribute;
  3252. } else {
  3253. const IdentifierInfo *II = Tok.getIdentifierInfo();
  3254. if (II->isStr("push"))
  3255. Info->Action = PragmaAttributeInfo::Push;
  3256. else if (II->isStr("pop"))
  3257. Info->Action = PragmaAttributeInfo::Pop;
  3258. else {
  3259. PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
  3260. << PP.getSpelling(Tok);
  3261. return;
  3262. }
  3263. PP.Lex(Tok);
  3264. }
  3265. // Parse the actual attribute.
  3266. if ((Info->Action == PragmaAttributeInfo::Push && Tok.isNot(tok::eod)) ||
  3267. Info->Action == PragmaAttributeInfo::Attribute) {
  3268. if (Tok.isNot(tok::l_paren)) {
  3269. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
  3270. return;
  3271. }
  3272. PP.Lex(Tok);
  3273. // Lex the attribute tokens.
  3274. SmallVector<Token, 16> AttributeTokens;
  3275. int OpenParens = 1;
  3276. while (Tok.isNot(tok::eod)) {
  3277. if (Tok.is(tok::l_paren))
  3278. OpenParens++;
  3279. else if (Tok.is(tok::r_paren)) {
  3280. OpenParens--;
  3281. if (OpenParens == 0)
  3282. break;
  3283. }
  3284. AttributeTokens.push_back(Tok);
  3285. PP.Lex(Tok);
  3286. }
  3287. if (AttributeTokens.empty()) {
  3288. PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
  3289. return;
  3290. }
  3291. if (Tok.isNot(tok::r_paren)) {
  3292. PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
  3293. return;
  3294. }
  3295. SourceLocation EndLoc = Tok.getLocation();
  3296. PP.Lex(Tok);
  3297. // Terminate the attribute for parsing.
  3298. Token EOFTok;
  3299. EOFTok.startToken();
  3300. EOFTok.setKind(tok::eof);
  3301. EOFTok.setLocation(EndLoc);
  3302. AttributeTokens.push_back(EOFTok);
  3303. markAsReinjectedForRelexing(AttributeTokens);
  3304. Info->Tokens =
  3305. llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
  3306. }
  3307. if (Tok.isNot(tok::eod))
  3308. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3309. << "clang attribute";
  3310. // Generate the annotated pragma token.
  3311. auto TokenArray = std::make_unique<Token[]>(1);
  3312. TokenArray[0].startToken();
  3313. TokenArray[0].setKind(tok::annot_pragma_attribute);
  3314. TokenArray[0].setLocation(FirstToken.getLocation());
  3315. TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
  3316. TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
  3317. PP.EnterTokenStream(std::move(TokenArray), 1,
  3318. /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
  3319. }
  3320. // Handle '#pragma clang max_tokens 12345'.
  3321. void PragmaMaxTokensHereHandler::HandlePragma(Preprocessor &PP,
  3322. PragmaIntroducer Introducer,
  3323. Token &Tok) {
  3324. PP.Lex(Tok);
  3325. if (Tok.is(tok::eod)) {
  3326. PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
  3327. << "clang max_tokens_here" << /*Expected=*/true << "integer";
  3328. return;
  3329. }
  3330. SourceLocation Loc = Tok.getLocation();
  3331. uint64_t MaxTokens;
  3332. if (Tok.isNot(tok::numeric_constant) ||
  3333. !PP.parseSimpleIntegerLiteral(Tok, MaxTokens)) {
  3334. PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
  3335. << "clang max_tokens_here";
  3336. return;
  3337. }
  3338. if (Tok.isNot(tok::eod)) {
  3339. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3340. << "clang max_tokens_here";
  3341. return;
  3342. }
  3343. if (PP.getTokenCount() > MaxTokens) {
  3344. PP.Diag(Loc, diag::warn_max_tokens)
  3345. << PP.getTokenCount() << (unsigned)MaxTokens;
  3346. }
  3347. }
  3348. // Handle '#pragma clang max_tokens_total 12345'.
  3349. void PragmaMaxTokensTotalHandler::HandlePragma(Preprocessor &PP,
  3350. PragmaIntroducer Introducer,
  3351. Token &Tok) {
  3352. PP.Lex(Tok);
  3353. if (Tok.is(tok::eod)) {
  3354. PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
  3355. << "clang max_tokens_total" << /*Expected=*/true << "integer";
  3356. return;
  3357. }
  3358. SourceLocation Loc = Tok.getLocation();
  3359. uint64_t MaxTokens;
  3360. if (Tok.isNot(tok::numeric_constant) ||
  3361. !PP.parseSimpleIntegerLiteral(Tok, MaxTokens)) {
  3362. PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
  3363. << "clang max_tokens_total";
  3364. return;
  3365. }
  3366. if (Tok.isNot(tok::eod)) {
  3367. PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
  3368. << "clang max_tokens_total";
  3369. return;
  3370. }
  3371. PP.overrideMaxTokens(MaxTokens, Loc);
  3372. }