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