27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/StringSwitch.h"
35 explicit PragmaAlignHandler() : PragmaHandler(
"align") {}
36 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
37 Token &FirstToken)
override;
41 explicit PragmaGCCVisibilityHandler() : PragmaHandler(
"visibility") {}
42 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
43 Token &FirstToken)
override;
47 explicit PragmaOptionsHandler() : PragmaHandler(
"options") {}
48 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
49 Token &FirstToken)
override;
53 explicit PragmaPackHandler() : PragmaHandler(
"pack") {}
54 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
55 Token &FirstToken)
override;
59 explicit PragmaClangSectionHandler(Sema &S)
60 : PragmaHandler(
"section"), Actions(S) {}
61 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
62 Token &FirstToken)
override;
69 explicit PragmaMSStructHandler() : PragmaHandler(
"ms_struct") {}
70 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
71 Token &FirstToken)
override;
75 PragmaUnusedHandler() : PragmaHandler(
"unused") {}
76 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
77 Token &FirstToken)
override;
81 explicit PragmaWeakHandler() : PragmaHandler(
"weak") {}
82 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
83 Token &FirstToken)
override;
87 explicit PragmaRedefineExtnameHandler() : PragmaHandler(
"redefine_extname") {}
88 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
89 Token &FirstToken)
override;
93 PragmaOpenCLExtensionHandler() : PragmaHandler(
"EXTENSION") {}
94 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
95 Token &FirstToken)
override;
100 PragmaFPContractHandler() : PragmaHandler(
"FP_CONTRACT") {}
101 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
102 Token &FirstToken)
override;
109 PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler(
"FENV_ACCESS") {}
111 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
112 Token &
Tok)
override {
113 Token PragmaName =
Tok;
125 Toks[0].startToken();
126 Toks[0].setKind(tok::annot_pragma_fenv_access);
129 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
131 PP.EnterTokenStream(Toks,
true,
137struct PragmaSTDC_CX_LIMITED_RANGEHandler :
public PragmaHandler {
138 PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler(
"CX_LIMITED_RANGE") {}
140 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
141 Token &
Tok)
override {
146 MutableArrayRef<Token> Toks(
149 Toks[0].startToken();
150 Toks[0].setKind(tok::annot_pragma_cx_limited_range);
153 Toks[0].setAnnotationValue(
154 reinterpret_cast<void *
>(
static_cast<uintptr_t>(OOS)));
155 PP.EnterTokenStream(Toks,
true,
162 PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler(
"FENV_ROUND") {}
164 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
165 Token &
Tok)
override;
170 PragmaSTDC_UnknownHandler() =
default;
172 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
173 Token &UnknownTok)
override {
175 PP.
Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
180 PragmaFPHandler() : PragmaHandler(
"fp") {}
181 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
182 Token &FirstToken)
override;
188template <diag::kind IgnoredDiag>
190 PragmaNoSupportHandler(StringRef Name) : PragmaHandler(Name) {}
191 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
192 Token &FirstToken)
override;
195struct PragmaNoOpenMPHandler
196 :
public PragmaNoSupportHandler<diag::warn_pragma_omp_ignored> {
197 PragmaNoOpenMPHandler() : PragmaNoSupportHandler(
"omp") {}
200struct PragmaNoOpenACCHandler
201 :
public PragmaNoSupportHandler<diag::warn_pragma_acc_ignored> {
202 PragmaNoOpenACCHandler() : PragmaNoSupportHandler(
"acc") {}
211 PragmaSupportHandler(StringRef Name) : PragmaHandler(Name) {}
212 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
213 Token &FirstToken)
override;
216struct PragmaOpenMPHandler
217 :
public PragmaSupportHandler<tok::annot_pragma_openmp,
218 tok::annot_pragma_openmp_end,
219 diag::err_omp_unexpected_directive> {
220 PragmaOpenMPHandler() : PragmaSupportHandler(
"omp") {}
223struct PragmaOpenACCHandler
224 :
public PragmaSupportHandler<tok::annot_pragma_openacc,
225 tok::annot_pragma_openacc_end,
226 diag::err_acc_unexpected_directive> {
227 PragmaOpenACCHandler() : PragmaSupportHandler(
"acc") {}
232 PragmaCommentHandler(Sema &Actions)
233 : PragmaHandler(
"comment"), Actions(Actions) {}
234 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
235 Token &FirstToken)
override;
242 PragmaDetectMismatchHandler(Sema &Actions)
243 : PragmaHandler(
"detect_mismatch"), Actions(Actions) {}
244 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
245 Token &FirstToken)
override;
252 PragmaFloatControlHandler(Sema &Actions)
253 : PragmaHandler(
"float_control") {}
254 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
255 Token &FirstToken)
override;
259 explicit PragmaMSPointersToMembers() : PragmaHandler(
"pointers_to_members") {}
260 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
261 Token &FirstToken)
override;
265 explicit PragmaMSVtorDisp() : PragmaHandler(
"vtordisp") {}
266 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
267 Token &FirstToken)
override;
271 explicit PragmaMSPragma(
const char *name) : PragmaHandler(
name) {}
272 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
273 Token &FirstToken)
override;
278 PragmaOptimizeHandler(Sema &S)
279 : PragmaHandler(
"optimize"), Actions(S) {}
280 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
281 Token &FirstToken)
override;
288 PragmaLoopHintHandler() : PragmaHandler(
"loop") {}
289 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
290 Token &FirstToken)
override;
294 PragmaUnrollHintHandler(
const char *name) : PragmaHandler(
name) {}
295 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
296 Token &FirstToken)
override;
300 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler(
"runtime_checks") {}
305 PragmaMSFenvAccessHandler() : PragmaHandler(
"fenv_access") {}
306 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
307 Token &FirstToken)
override {
329 if (II->
isStr(
"on")) {
332 }
else if (II->
isStr(
"off")) {
352 MutableArrayRef<Token> Toks(
354 Toks[0].startToken();
355 Toks[0].setKind(tok::annot_pragma_fenv_access_ms);
358 Toks[0].setAnnotationValue(
359 reinterpret_cast<void*
>(
static_cast<uintptr_t>(OOS)));
360 PP.EnterTokenStream(Toks,
true,
365struct PragmaForceCUDAHostDeviceHandler :
public PragmaHandler {
366 PragmaForceCUDAHostDeviceHandler(Sema &Actions)
367 : PragmaHandler(
"force_cuda_host_device"), Actions(Actions) {}
368 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
369 Token &FirstToken)
override;
377 PragmaAttributeHandler(AttributeFactory &AttrFactory)
378 : PragmaHandler(
"attribute"), AttributesForPragmaAttribute(AttrFactory) {}
379 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
380 Token &FirstToken)
override;
383 ParsedAttributes AttributesForPragmaAttribute;
387 PragmaMaxTokensHereHandler() : PragmaHandler(
"max_tokens_here") {}
388 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
389 Token &FirstToken)
override;
393 PragmaMaxTokensTotalHandler() : PragmaHandler(
"max_tokens_total") {}
394 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
395 Token &FirstToken)
override;
399 PragmaRISCVHandler(Sema &Actions)
400 : PragmaHandler(
"riscv"), Actions(Actions) {}
401 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
402 Token &FirstToken)
override;
414void Parser::initializePragmaHandlers() {
415 AlignHandler = std::make_unique<PragmaAlignHandler>();
416 PP.AddPragmaHandler(AlignHandler.get());
418 GCCVisibilityHandler = std::make_unique<PragmaGCCVisibilityHandler>();
419 PP.AddPragmaHandler(
"GCC", GCCVisibilityHandler.get());
421 OptionsHandler = std::make_unique<PragmaOptionsHandler>();
422 PP.AddPragmaHandler(OptionsHandler.get());
424 PackHandler = std::make_unique<PragmaPackHandler>();
425 PP.AddPragmaHandler(PackHandler.get());
427 MSStructHandler = std::make_unique<PragmaMSStructHandler>();
428 PP.AddPragmaHandler(MSStructHandler.get());
430 UnusedHandler = std::make_unique<PragmaUnusedHandler>();
431 PP.AddPragmaHandler(UnusedHandler.get());
433 WeakHandler = std::make_unique<PragmaWeakHandler>();
434 PP.AddPragmaHandler(WeakHandler.get());
436 RedefineExtnameHandler = std::make_unique<PragmaRedefineExtnameHandler>();
437 PP.AddPragmaHandler(RedefineExtnameHandler.get());
439 FPContractHandler = std::make_unique<PragmaFPContractHandler>();
440 PP.AddPragmaHandler(
"STDC", FPContractHandler.get());
442 STDCFenvAccessHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
443 PP.AddPragmaHandler(
"STDC", STDCFenvAccessHandler.get());
445 STDCFenvRoundHandler = std::make_unique<PragmaSTDC_FENV_ROUNDHandler>();
446 PP.AddPragmaHandler(
"STDC", STDCFenvRoundHandler.get());
448 STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
449 PP.AddPragmaHandler(
"STDC", STDCCXLIMITHandler.get());
451 STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
452 PP.AddPragmaHandler(
"STDC", STDCUnknownHandler.get());
454 PCSectionHandler = std::make_unique<PragmaClangSectionHandler>(Actions);
455 PP.AddPragmaHandler(
"clang", PCSectionHandler.get());
458 OpenCLExtensionHandler = std::make_unique<PragmaOpenCLExtensionHandler>();
459 PP.AddPragmaHandler(
"OPENCL", OpenCLExtensionHandler.get());
461 PP.AddPragmaHandler(
"OPENCL", FPContractHandler.get());
464 OpenMPHandler = std::make_unique<PragmaOpenMPHandler>();
466 OpenMPHandler = std::make_unique<PragmaNoOpenMPHandler>();
467 PP.AddPragmaHandler(OpenMPHandler.get());
470 OpenACCHandler = std::make_unique<PragmaOpenACCHandler>();
472 OpenACCHandler = std::make_unique<PragmaNoOpenACCHandler>();
473 PP.AddPragmaHandler(OpenACCHandler.get());
477 MSCommentHandler = std::make_unique<PragmaCommentHandler>(Actions);
478 PP.AddPragmaHandler(MSCommentHandler.get());
481 FloatControlHandler = std::make_unique<PragmaFloatControlHandler>(Actions);
482 PP.AddPragmaHandler(FloatControlHandler.get());
484 MSDetectMismatchHandler =
485 std::make_unique<PragmaDetectMismatchHandler>(Actions);
486 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
487 MSPointersToMembers = std::make_unique<PragmaMSPointersToMembers>();
488 PP.AddPragmaHandler(MSPointersToMembers.get());
489 MSVtorDisp = std::make_unique<PragmaMSVtorDisp>();
490 PP.AddPragmaHandler(MSVtorDisp.get());
491 MSInitSeg = std::make_unique<PragmaMSPragma>(
"init_seg");
492 PP.AddPragmaHandler(MSInitSeg.get());
493 MSDataSeg = std::make_unique<PragmaMSPragma>(
"data_seg");
494 PP.AddPragmaHandler(MSDataSeg.get());
495 MSBSSSeg = std::make_unique<PragmaMSPragma>(
"bss_seg");
496 PP.AddPragmaHandler(MSBSSSeg.get());
497 MSConstSeg = std::make_unique<PragmaMSPragma>(
"const_seg");
498 PP.AddPragmaHandler(MSConstSeg.get());
499 MSCodeSeg = std::make_unique<PragmaMSPragma>(
"code_seg");
500 PP.AddPragmaHandler(MSCodeSeg.get());
501 MSSection = std::make_unique<PragmaMSPragma>(
"section");
502 PP.AddPragmaHandler(MSSection.get());
503 MSStrictGuardStackCheck =
504 std::make_unique<PragmaMSPragma>(
"strict_gs_check");
505 PP.AddPragmaHandler(MSStrictGuardStackCheck.get());
506 MSFunction = std::make_unique<PragmaMSPragma>(
"function");
507 PP.AddPragmaHandler(MSFunction.get());
508 MSAllocText = std::make_unique<PragmaMSPragma>(
"alloc_text");
509 PP.AddPragmaHandler(MSAllocText.get());
510 MSOptimize = std::make_unique<PragmaMSPragma>(
"optimize");
511 PP.AddPragmaHandler(MSOptimize.get());
512 MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
513 PP.AddPragmaHandler(MSRuntimeChecks.get());
514 MSIntrinsic = std::make_unique<PragmaMSPragma>(
"intrinsic");
515 PP.AddPragmaHandler(MSIntrinsic.get());
516 MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
517 PP.AddPragmaHandler(MSFenvAccess.get());
521 CUDAForceHostDeviceHandler =
522 std::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
523 PP.AddPragmaHandler(
"clang", CUDAForceHostDeviceHandler.get());
526 OptimizeHandler = std::make_unique<PragmaOptimizeHandler>(Actions);
527 PP.AddPragmaHandler(
"clang", OptimizeHandler.get());
529 LoopHintHandler = std::make_unique<PragmaLoopHintHandler>();
530 PP.AddPragmaHandler(
"clang", LoopHintHandler.get());
532 UnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>(
"unroll");
533 PP.AddPragmaHandler(UnrollHintHandler.get());
534 PP.AddPragmaHandler(
"GCC", UnrollHintHandler.get());
536 NoUnrollHintHandler = std::make_unique<PragmaUnrollHintHandler>(
"nounroll");
537 PP.AddPragmaHandler(NoUnrollHintHandler.get());
538 PP.AddPragmaHandler(
"GCC", NoUnrollHintHandler.get());
540 UnrollAndJamHintHandler =
541 std::make_unique<PragmaUnrollHintHandler>(
"unroll_and_jam");
542 PP.AddPragmaHandler(UnrollAndJamHintHandler.get());
544 NoUnrollAndJamHintHandler =
545 std::make_unique<PragmaUnrollHintHandler>(
"nounroll_and_jam");
546 PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
548 FPHandler = std::make_unique<PragmaFPHandler>();
549 PP.AddPragmaHandler(
"clang", FPHandler.get());
551 AttributePragmaHandler =
552 std::make_unique<PragmaAttributeHandler>(AttrFactory);
553 PP.AddPragmaHandler(
"clang", AttributePragmaHandler.get());
555 MaxTokensHerePragmaHandler = std::make_unique<PragmaMaxTokensHereHandler>();
556 PP.AddPragmaHandler(
"clang", MaxTokensHerePragmaHandler.get());
558 MaxTokensTotalPragmaHandler = std::make_unique<PragmaMaxTokensTotalHandler>();
559 PP.AddPragmaHandler(
"clang", MaxTokensTotalPragmaHandler.get());
562 RISCVPragmaHandler = std::make_unique<PragmaRISCVHandler>(Actions);
563 PP.AddPragmaHandler(
"clang", RISCVPragmaHandler.get());
567void Parser::resetPragmaHandlers() {
569 PP.RemovePragmaHandler(AlignHandler.get());
570 AlignHandler.reset();
571 PP.RemovePragmaHandler(
"GCC", GCCVisibilityHandler.get());
572 GCCVisibilityHandler.reset();
573 PP.RemovePragmaHandler(OptionsHandler.get());
574 OptionsHandler.reset();
575 PP.RemovePragmaHandler(PackHandler.get());
577 PP.RemovePragmaHandler(MSStructHandler.get());
578 MSStructHandler.reset();
579 PP.RemovePragmaHandler(UnusedHandler.get());
580 UnusedHandler.reset();
581 PP.RemovePragmaHandler(WeakHandler.get());
583 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
584 RedefineExtnameHandler.reset();
587 PP.RemovePragmaHandler(
"OPENCL", OpenCLExtensionHandler.get());
588 OpenCLExtensionHandler.reset();
589 PP.RemovePragmaHandler(
"OPENCL", FPContractHandler.get());
591 PP.RemovePragmaHandler(OpenMPHandler.get());
592 OpenMPHandler.reset();
594 PP.RemovePragmaHandler(OpenACCHandler.get());
595 OpenACCHandler.reset();
599 PP.RemovePragmaHandler(MSCommentHandler.get());
600 MSCommentHandler.reset();
603 PP.RemovePragmaHandler(
"clang", PCSectionHandler.get());
604 PCSectionHandler.reset();
606 PP.RemovePragmaHandler(FloatControlHandler.get());
607 FloatControlHandler.reset();
609 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
610 MSDetectMismatchHandler.reset();
611 PP.RemovePragmaHandler(MSPointersToMembers.get());
612 MSPointersToMembers.reset();
613 PP.RemovePragmaHandler(MSVtorDisp.get());
615 PP.RemovePragmaHandler(MSInitSeg.get());
617 PP.RemovePragmaHandler(MSDataSeg.get());
619 PP.RemovePragmaHandler(MSBSSSeg.get());
621 PP.RemovePragmaHandler(MSConstSeg.get());
623 PP.RemovePragmaHandler(MSCodeSeg.get());
625 PP.RemovePragmaHandler(MSSection.get());
627 PP.RemovePragmaHandler(MSStrictGuardStackCheck.get());
628 MSStrictGuardStackCheck.reset();
629 PP.RemovePragmaHandler(MSFunction.get());
631 PP.RemovePragmaHandler(MSAllocText.get());
633 PP.RemovePragmaHandler(MSRuntimeChecks.get());
634 MSRuntimeChecks.reset();
635 PP.RemovePragmaHandler(MSIntrinsic.get());
637 PP.RemovePragmaHandler(MSOptimize.get());
639 PP.RemovePragmaHandler(MSFenvAccess.get());
640 MSFenvAccess.reset();
644 PP.RemovePragmaHandler(
"clang", CUDAForceHostDeviceHandler.get());
645 CUDAForceHostDeviceHandler.reset();
648 PP.RemovePragmaHandler(
"STDC", FPContractHandler.get());
649 FPContractHandler.reset();
651 PP.RemovePragmaHandler(
"STDC", STDCFenvAccessHandler.get());
652 STDCFenvAccessHandler.reset();
654 PP.RemovePragmaHandler(
"STDC", STDCFenvRoundHandler.get());
655 STDCFenvRoundHandler.reset();
657 PP.RemovePragmaHandler(
"STDC", STDCCXLIMITHandler.get());
658 STDCCXLIMITHandler.reset();
660 PP.RemovePragmaHandler(
"STDC", STDCUnknownHandler.get());
661 STDCUnknownHandler.reset();
663 PP.RemovePragmaHandler(
"clang", OptimizeHandler.get());
664 OptimizeHandler.reset();
666 PP.RemovePragmaHandler(
"clang", LoopHintHandler.get());
667 LoopHintHandler.reset();
669 PP.RemovePragmaHandler(UnrollHintHandler.get());
670 PP.RemovePragmaHandler(
"GCC", UnrollHintHandler.get());
671 UnrollHintHandler.reset();
673 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
674 PP.RemovePragmaHandler(
"GCC", NoUnrollHintHandler.get());
675 NoUnrollHintHandler.reset();
677 PP.RemovePragmaHandler(UnrollAndJamHintHandler.get());
678 UnrollAndJamHintHandler.reset();
680 PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
681 NoUnrollAndJamHintHandler.reset();
683 PP.RemovePragmaHandler(
"clang", FPHandler.get());
686 PP.RemovePragmaHandler(
"clang", AttributePragmaHandler.get());
687 AttributePragmaHandler.reset();
689 PP.RemovePragmaHandler(
"clang", MaxTokensHerePragmaHandler.get());
690 MaxTokensHerePragmaHandler.reset();
692 PP.RemovePragmaHandler(
"clang", MaxTokensTotalPragmaHandler.get());
693 MaxTokensTotalPragmaHandler.reset();
696 PP.RemovePragmaHandler(
"clang", RISCVPragmaHandler.get());
697 RISCVPragmaHandler.reset();
701void Parser::HandlePragmaUnused() {
702 assert(Tok.is(tok::annot_pragma_unused));
703 SourceLocation UnusedLoc = ConsumeAnnotationToken();
704 Actions.ActOnPragmaUnused(Tok,
getCurScope(), UnusedLoc);
708void Parser::HandlePragmaVisibility() {
709 assert(Tok.is(tok::annot_pragma_vis));
710 const IdentifierInfo *VisType =
711 static_cast<IdentifierInfo *
>(Tok.getAnnotationValue());
712 SourceLocation VisLoc = ConsumeAnnotationToken();
713 Actions.ActOnPragmaVisibility(VisType, VisLoc);
716void Parser::HandlePragmaPack() {
717 assert(Tok.is(tok::annot_pragma_pack));
718 Sema::PragmaPackInfo *Info =
719 static_cast<Sema::PragmaPackInfo *
>(Tok.getAnnotationValue());
720 SourceLocation PragmaLoc = Tok.getLocation();
723 Alignment = Actions.ActOnNumericConstant(Info->
Alignment);
725 ConsumeAnnotationToken();
733 ConsumeAnnotationToken();
736void Parser::HandlePragmaMSStruct() {
737 assert(Tok.is(tok::annot_pragma_msstruct));
739 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
740 Actions.ActOnPragmaMSStruct(Kind);
741 ConsumeAnnotationToken();
744void Parser::HandlePragmaAlign() {
745 assert(Tok.is(tok::annot_pragma_align));
747 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
748 Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
751 ConsumeAnnotationToken();
754void Parser::HandlePragmaDump() {
755 assert(Tok.is(tok::annot_pragma_dump));
756 ConsumeAnnotationToken();
757 if (Tok.is(tok::eod)) {
758 PP.Diag(Tok, diag::warn_pragma_debug_missing_argument) <<
"dump";
760 if (Tok.isNot(tok::identifier)) {
761 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_argument);
763 ExpectAndConsume(tok::eod);
766 IdentifierInfo *II = Tok.getIdentifierInfo();
767 Actions.ActOnPragmaDump(
getCurScope(), Tok.getLocation(), II);
770 SourceLocation StartLoc = Tok.getLocation();
771 EnterExpressionEvaluationContext Ctx(
777 PP.Diag(StartLoc, diag::warn_pragma_debug_dependent_argument)
779 << SourceRange(StartLoc, Tok.getLocation());
781 Actions.ActOnPragmaDump(E.
get());
785 ExpectAndConsume(tok::eod);
788void Parser::HandlePragmaWeak() {
789 assert(Tok.is(tok::annot_pragma_weak));
790 SourceLocation PragmaLoc = ConsumeAnnotationToken();
791 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
796void Parser::HandlePragmaWeakAlias() {
797 assert(Tok.is(tok::annot_pragma_weakalias));
798 SourceLocation PragmaLoc = ConsumeAnnotationToken();
799 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
800 SourceLocation WeakNameLoc = Tok.getLocation();
802 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
803 SourceLocation AliasNameLoc = Tok.getLocation();
805 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
806 WeakNameLoc, AliasNameLoc);
810void Parser::HandlePragmaRedefineExtname() {
811 assert(Tok.is(tok::annot_pragma_redefine_extname));
812 SourceLocation RedefLoc = ConsumeAnnotationToken();
813 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
814 SourceLocation RedefNameLoc = Tok.getLocation();
816 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
817 SourceLocation AliasNameLoc = Tok.getLocation();
819 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
820 RedefNameLoc, AliasNameLoc);
823void Parser::HandlePragmaFPContract() {
824 assert(Tok.is(tok::annot_pragma_fp_contract));
827 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
847 SourceLocation PragmaLoc = ConsumeAnnotationToken();
848 Actions.ActOnPragmaFPContract(PragmaLoc, FPC);
851void Parser::HandlePragmaFloatControl() {
852 assert(Tok.is(tok::annot_pragma_float_control));
863 SourceLocation PragmaLoc = ConsumeAnnotationToken();
864 Actions.ActOnPragmaFloatControl(PragmaLoc, Action, Kind);
867void Parser::HandlePragmaFEnvAccess() {
868 assert(Tok.is(tok::annot_pragma_fenv_access) ||
869 Tok.is(tok::annot_pragma_fenv_access_ms));
872 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
887 SourceLocation PragmaLoc = ConsumeAnnotationToken();
888 Actions.ActOnPragmaFEnvAccess(PragmaLoc, IsEnabled);
891void Parser::HandlePragmaFEnvRound() {
892 assert(Tok.is(tok::annot_pragma_fenv_round));
893 auto RM =
static_cast<llvm::RoundingMode
>(
894 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
896 SourceLocation PragmaLoc = ConsumeAnnotationToken();
897 Actions.ActOnPragmaFEnvRound(PragmaLoc, RM);
900void Parser::HandlePragmaCXLimitedRange() {
901 assert(Tok.is(tok::annot_pragma_cx_limited_range));
903 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
921 SourceLocation PragmaLoc = ConsumeAnnotationToken();
922 Actions.ActOnPragmaCXLimitedRange(PragmaLoc, Range);
927 assert(Tok.is(tok::annot_pragma_captured));
928 ConsumeAnnotationToken();
930 if (Tok.isNot(tok::l_brace)) {
931 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
935 SourceLocation Loc = Tok.getLocation();
943 CapturedRegionScope.Exit();
946 Actions.ActOnCapturedRegionError();
950 return Actions.ActOnCapturedRegionEnd(R.get());
954 enum OpenCLExtState :
char {
955 Disable, Enable, Begin, End
957 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
960void Parser::HandlePragmaOpenCLExtension() {
961 assert(Tok.is(tok::annot_pragma_opencl_extension));
962 OpenCLExtData *
Data =
static_cast<OpenCLExtData*
>(Tok.getAnnotationValue());
963 auto State =
Data->second;
964 auto Ident =
Data->first;
965 SourceLocation NameLoc = Tok.getLocation();
966 ConsumeAnnotationToken();
968 auto &Opt = Actions.getOpenCLOptions();
969 auto Name = Ident->getName();
974 if (State == Disable)
977 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
978 }
else if (State == Begin) {
979 if (!Opt.isKnown(Name) || !Opt.isSupported(Name,
getLangOpts())) {
983 Opt.acceptsPragma(Name);
985 }
else if (State == End) {
988 }
else if (!Opt.isKnown(Name) || !Opt.isWithPragma(Name))
989 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
990 else if (Opt.isSupportedExtension(Name,
getLangOpts()))
991 Opt.enable(Name, State == Enable);
992 else if (Opt.isSupportedCoreOrOptionalCore(Name,
getLangOpts()))
993 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
995 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
998void Parser::HandlePragmaMSPointersToMembers() {
999 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
1002 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
1003 SourceLocation PragmaLoc = ConsumeAnnotationToken();
1004 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
1007void Parser::HandlePragmaMSVtorDisp() {
1008 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
1013 SourceLocation PragmaLoc = ConsumeAnnotationToken();
1014 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
1017void Parser::HandlePragmaMSPragma() {
1018 assert(Tok.is(tok::annot_pragma_ms_pragma));
1021 (std::pair<std::unique_ptr<Token[]>,
size_t> *)Tok.getAnnotationValue();
1022 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second,
true,
1024 SourceLocation PragmaLocation = ConsumeAnnotationToken();
1025 assert(Tok.isAnyIdentifier());
1026 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
1031 typedef bool (
Parser::*PragmaHandler)(StringRef, SourceLocation);
1032 PragmaHandler Handler =
1033 llvm::StringSwitch<PragmaHandler>(PragmaName)
1034 .Case(
"data_seg", &Parser::HandlePragmaMSSegment)
1035 .Case(
"bss_seg", &Parser::HandlePragmaMSSegment)
1036 .Case(
"const_seg", &Parser::HandlePragmaMSSegment)
1037 .Case(
"code_seg", &Parser::HandlePragmaMSSegment)
1038 .Case(
"section", &Parser::HandlePragmaMSSection)
1039 .Case(
"init_seg", &Parser::HandlePragmaMSInitSeg)
1040 .Case(
"strict_gs_check", &Parser::HandlePragmaMSStrictGuardStackCheck)
1041 .Case(
"function", &Parser::HandlePragmaMSFunction)
1042 .Case(
"alloc_text", &Parser::HandlePragmaMSAllocText)
1043 .Case(
"optimize", &Parser::HandlePragmaMSOptimize)
1044 .Case(
"intrinsic", &Parser::HandlePragmaMSIntrinsic);
1046 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
1049 while (Tok.isNot(tok::eof))
1055bool Parser::HandlePragmaMSSection(StringRef PragmaName,
1057 if (Tok.isNot(tok::l_paren)) {
1058 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
1063 if (Tok.isNot(tok::string_literal)) {
1064 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
1073 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1078 bool SectionFlagsAreDefault =
true;
1079 while (Tok.is(tok::comma)) {
1084 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
1089 if (!Tok.isAnyIdentifier()) {
1090 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
1095 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
1096 Tok.getIdentifierInfo()->getName())
1108 ? diag::warn_pragma_invalid_specific_action
1109 : diag::warn_pragma_unsupported_action)
1110 << PragmaName << Tok.getIdentifierInfo()->getName();
1113 SectionFlags |= Flag;
1114 SectionFlagsAreDefault =
false;
1119 if (SectionFlagsAreDefault)
1121 if (Tok.isNot(tok::r_paren)) {
1122 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
1126 if (Tok.isNot(tok::eof)) {
1127 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
1132 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
1136bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
1138 if (Tok.isNot(tok::l_paren)) {
1139 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
1144 StringRef SlotLabel;
1145 if (Tok.isAnyIdentifier()) {
1146 StringRef PushPop = Tok.getIdentifierInfo()->getName();
1147 if (PushPop ==
"push")
1149 else if (PushPop ==
"pop")
1152 PP.Diag(PragmaLocation,
1153 diag::warn_pragma_expected_section_push_pop_or_name)
1159 if (Tok.is(tok::comma)) {
1162 if (Tok.isAnyIdentifier()) {
1163 SlotLabel = Tok.getIdentifierInfo()->getName();
1165 if (Tok.is(tok::comma))
1167 else if (Tok.isNot(tok::r_paren)) {
1168 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
1173 }
else if (Tok.isNot(tok::r_paren)) {
1174 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
1180 StringLiteral *SegmentName =
nullptr;
1181 if (Tok.isNot(tok::r_paren)) {
1182 if (Tok.isNot(tok::string_literal)) {
1184 diag::warn_pragma_expected_section_name :
1185 diag::warn_pragma_expected_section_label_or_name :
1186 diag::warn_pragma_expected_section_push_pop_or_name;
1187 PP.Diag(PragmaLocation, DiagID) << PragmaName;
1195 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1203 if (Tok.isNot(tok::r_paren)) {
1204 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
1208 if (Tok.isNot(tok::eof)) {
1209 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
1214 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
1215 SegmentName, PragmaName);
1219bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
1221 if (
getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
1222 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
1226 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1231 StringLiteral *SegmentName =
nullptr;
1232 if (Tok.isAnyIdentifier()) {
1233 auto *II = Tok.getIdentifierInfo();
1234 StringRef Section = llvm::StringSwitch<StringRef>(II->
getName())
1235 .Case(
"compiler",
"\".CRT$XCC\"")
1236 .Case(
"lib",
"\".CRT$XCL\"")
1237 .Case(
"user",
"\".CRT$XCU\"")
1240 if (!Section.empty()) {
1244 Toks[0].
setKind(tok::string_literal);
1252 }
else if (Tok.is(tok::string_literal)) {
1258 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1266 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
1270 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1272 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1276 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
1280bool Parser::HandlePragmaMSStrictGuardStackCheck(
1282 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1287 if (Tok.is(tok::identifier)) {
1288 StringRef PushPop = Tok.getIdentifierInfo()->getName();
1289 if (PushPop ==
"push") {
1292 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_punc,
1295 }
else if (PushPop ==
"pop") {
1303 const IdentifierInfo *II = Tok.getIdentifierInfo();
1304 if (II && II->
isStr(
"off")) {
1307 }
else if (II && II->
isStr(
"on")) {
1311 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1318 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1322 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1326 Actions.ActOnPragmaMSStrictGuardStackCheck(PragmaLocation, Action,
Value);
1330bool Parser::HandlePragmaMSAllocText(StringRef PragmaName,
1332 Token FirstTok = Tok;
1333 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1338 if (Tok.is(tok::string_literal)) {
1344 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1349 }
else if (Tok.is(tok::identifier)) {
1350 Section = Tok.getIdentifierInfo()->getName();
1353 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
1358 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_comma,
1362 SmallVector<std::tuple<IdentifierInfo *, SourceLocation>> Functions;
1364 if (Tok.isNot(tok::identifier)) {
1365 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1370 IdentifierInfo *II = Tok.getIdentifierInfo();
1371 Functions.emplace_back(II, Tok.getLocation());
1374 if (Tok.isNot(tok::comma))
1379 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1381 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1385 Actions.ActOnPragmaMSAllocText(FirstTok.
getLocation(), Section, Functions);
1391 std::string ClangLoopStr(
"clang loop ");
1394 return std::string(llvm::StringSwitch<StringRef>(Str)
1395 .Case(
"loop", ClangLoopStr)
1396 .Case(
"unroll_and_jam", Str)
1397 .Case(
"unroll", Str)
1401bool Parser::HandlePragmaLoopHint(
LoopHint &Hint) {
1402 assert(Tok.is(tok::annot_pragma_loop_hint));
1403 PragmaLoopHintInfo *Info =
1404 static_cast<PragmaLoopHintInfo *
>(Tok.getAnnotationValue());
1412 IdentifierInfo *OptionInfo = Info->
Option.
is(tok::identifier)
1418 llvm::ArrayRef<Token> Toks = Info->
Toks;
1423 llvm::StringSwitch<bool>(PragmaNameInfo->
getName())
1424 .Cases({
"unroll",
"nounroll",
"unroll_and_jam",
"nounroll_and_jam"},
1428 if (Toks.empty() && IsLoopHint) {
1429 ConsumeAnnotationToken();
1436 assert(!Toks.empty() &&
1437 "PragmaLoopHintInfo::Toks must contain at least one token.");
1440 bool OptionUnroll =
false;
1441 bool OptionUnrollAndJam =
false;
1442 bool OptionDistribute =
false;
1443 bool OptionPipelineDisabled =
false;
1444 bool StateOption =
false;
1446 OptionUnroll = OptionInfo->
isStr(
"unroll");
1447 OptionUnrollAndJam = OptionInfo->
isStr(
"unroll_and_jam");
1448 OptionDistribute = OptionInfo->
isStr(
"distribute");
1449 OptionPipelineDisabled = OptionInfo->
isStr(
"pipeline");
1450 StateOption = llvm::StringSwitch<bool>(OptionInfo->
getName())
1451 .Case(
"vectorize",
true)
1452 .Case(
"interleave",
true)
1453 .Case(
"vectorize_predicate",
true)
1455 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1456 OptionPipelineDisabled;
1459 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1460 !OptionDistribute && !OptionPipelineDisabled;
1462 if (Toks[0].
is(tok::eof)) {
1463 ConsumeAnnotationToken();
1464 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1466 << (OptionUnroll || OptionUnrollAndJam)
1473 ConsumeAnnotationToken();
1474 SourceLocation StateLoc = Toks[0].getLocation();
1475 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1477 bool Valid = StateInfo &&
1478 llvm::StringSwitch<bool>(StateInfo->
getName())
1479 .Case(
"disable",
true)
1480 .Case(
"enable", !OptionPipelineDisabled)
1481 .Case(
"full", OptionUnroll || OptionUnrollAndJam)
1482 .Case(
"assume_safety", AssumeSafetyArg)
1485 if (OptionPipelineDisabled) {
1486 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1488 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1489 << (OptionUnroll || OptionUnrollAndJam)
1494 if (Toks.size() > 2)
1495 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1497 Hint.
StateLoc =
new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1498 }
else if (OptionInfo && OptionInfo->
getName() ==
"vectorize_width") {
1499 PP.EnterTokenStream(Toks,
false,
1501 ConsumeAnnotationToken();
1503 SourceLocation StateLoc = Toks[0].getLocation();
1504 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1505 StringRef IsScalableStr = StateInfo ? StateInfo->
getName() :
"";
1508 if (IsScalableStr ==
"scalable" || IsScalableStr ==
"fixed") {
1511 if (Toks.size() > 2) {
1512 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1514 while (Tok.isNot(tok::eof))
1518 Hint.
StateLoc =
new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1525 if (R.
isInvalid() && !Tok.is(tok::comma))
1526 Diag(Toks[0].getLocation(),
1527 diag::note_pragma_loop_invalid_vectorize_option);
1529 bool Arg2Error =
false;
1530 if (Tok.is(tok::comma)) {
1533 StateInfo = Tok.getIdentifierInfo();
1534 IsScalableStr = StateInfo->
getName();
1536 if (IsScalableStr !=
"scalable" && IsScalableStr !=
"fixed") {
1537 Diag(Tok.getLocation(),
1538 diag::err_pragma_loop_invalid_vectorize_option);
1542 new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1549 if (Tok.isNot(tok::eof)) {
1550 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1552 while (Tok.isNot(tok::eof))
1559 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation(),
1568 PP.EnterTokenStream(Toks,
false,
1570 ConsumeAnnotationToken();
1575 if (Tok.isNot(tok::eof)) {
1576 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1578 while (Tok.isNot(tok::eof))
1585 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation(),
1594 Info->
Toks.back().getLocation());
1599struct PragmaAttributeInfo {
1600 enum ActionType { Push,
Pop, Attribute };
1601 ParsedAttributes &Attributes;
1603 const IdentifierInfo *
Namespace =
nullptr;
1604 ArrayRef<Token> Tokens;
1606 PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1609#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1614 if (
Tok.is(tok::identifier))
1615 return Tok.getIdentifierInfo()->getName();
1623 using namespace attr;
1625#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1628#include "clang/Basic/AttrSubMatchRulesList.inc"
1630 llvm_unreachable(
"Invalid attribute subject match rule");
1638 PRef.
Diag(SubRuleLoc,
1639 diag::err_pragma_attribute_expected_subject_sub_identifier)
1641 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1652 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1653 << SubRuleName << PrimaryRuleName;
1654 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1660bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1668 if (AnyParens.expectAndConsume())
1676 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1679 std::pair<std::optional<attr::SubjectMatchRule>,
1680 std::optional<attr::SubjectMatchRule> (*)(StringRef,
bool)>
1681 Rule = isAttributeSubjectMatchRule(Name);
1683 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1691 if (
Parens.expectAndConsume())
1693 }
else if (
Parens.consumeOpen()) {
1694 if (!SubjectMatchRules
1696 std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1698 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1701 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1702 LastMatchRuleEndLoc = RuleLoc;
1708 if (SubRuleName.empty()) {
1714 if (SubRuleName ==
"unless") {
1717 if (
Parens.expectAndConsume())
1720 if (SubRuleName.empty()) {
1725 auto SubRuleOrNone =
Rule.second(SubRuleName,
true);
1726 if (!SubRuleOrNone) {
1727 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1729 SubRuleUnlessName, SubRuleLoc);
1732 SubRule = *SubRuleOrNone;
1734 if (
Parens.consumeClose())
1737 auto SubRuleOrNone =
Rule.second(SubRuleName,
false);
1738 if (!SubRuleOrNone) {
1740 SubRuleName, Tok.getLocation());
1743 SubRule = *SubRuleOrNone;
1746 SourceLocation RuleEndLoc = Tok.getLocation();
1747 LastMatchRuleEndLoc = RuleEndLoc;
1748 if (
Parens.consumeClose())
1750 if (!SubjectMatchRules
1751 .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1753 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1756 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1762 if (AnyParens.consumeClose())
1771enum class MissingAttributeSubjectRulesRecoveryPoint {
1779MissingAttributeSubjectRulesRecoveryPoint
1780getAttributeSubjectRulesRecoveryPointForToken(
const Token &
Tok) {
1782 if (II->
isStr(
"apply_to"))
1783 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1784 if (II->
isStr(
"any"))
1785 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1787 if (
Tok.
is(tok::equal))
1788 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1789 return MissingAttributeSubjectRulesRecoveryPoint::None;
1797 MissingAttributeSubjectRulesRecoveryPoint Point,
Parser &PRef) {
1803 MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1804 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1805 if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1807 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1808 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1809 FixIt +=
"apply_to";
1810 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1811 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1814 if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1821 Attribute.getMatchRules(PRef.
getLangOpts(), MatchRules);
1823 for (
const auto &Rule : MatchRules) {
1828 IsSupported[
Rule.first] =
true;
1830 IsMatchRuleAvailable &= IsSupported;
1832 if (IsMatchRuleAvailable.count() == 0) {
1838 bool NeedsComma =
false;
1840 if (!IsMatchRuleAvailable[I])
1854 if (FixItRange.getBegin() == FixItRange.getEnd())
1864void Parser::HandlePragmaAttribute() {
1865 assert(Tok.is(tok::annot_pragma_attribute) &&
1866 "Expected #pragma attribute annotation token");
1867 SourceLocation PragmaLoc = Tok.getLocation();
1868 auto *Info =
static_cast<PragmaAttributeInfo *
>(Tok.getAnnotationValue());
1869 if (Info->Action == PragmaAttributeInfo::Pop) {
1870 ConsumeAnnotationToken();
1871 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1875 assert((Info->Action == PragmaAttributeInfo::Push ||
1876 Info->Action == PragmaAttributeInfo::Attribute) &&
1877 "Unexpected #pragma attribute command");
1879 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1880 ConsumeAnnotationToken();
1881 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1885 PP.EnterTokenStream(Info->Tokens,
false,
1887 ConsumeAnnotationToken();
1889 ParsedAttributes &Attrs = Info->Attributes;
1892 auto SkipToEnd = [
this]() {
1897 if ((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1898 Tok.isRegularKeywordAttribute()) {
1900 ParseCXX11AttributeSpecifier(Attrs);
1901 }
else if (Tok.is(tok::kw___attribute)) {
1903 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1906 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1911 if (Tok.is(tok::code_completion)) {
1914 Actions.CodeCompletion().CodeCompleteAttribute(
1921 if (Tok.isNot(tok::identifier)) {
1922 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1926 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1929 if (Tok.isNot(tok::l_paren))
1930 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1931 ParsedAttr::Form::GNU());
1933 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1936 ParsedAttr::Form::GNU(),
1940 if (ExpectAndConsume(tok::r_paren))
1942 if (ExpectAndConsume(tok::r_paren))
1944 }
else if (Tok.is(tok::kw___declspec)) {
1945 ParseMicrosoftDeclSpecs(Attrs);
1947 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1948 if (Tok.getIdentifierInfo()) {
1952 Tok.getIdentifierInfo(),
nullptr,
1954 SourceLocation InsertStartLoc = Tok.getLocation();
1956 if (Tok.is(tok::l_paren)) {
1959 if (Tok.isNot(tok::r_paren))
1962 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1971 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1976 for (
const ParsedAttr &Attribute : Attrs) {
1977 if (!Attribute.isSupportedByPragmaAttribute()) {
1978 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1987 createExpectedAttributeSubjectRulesTokenDiagnostic(
1988 diag::err_expected, Attrs,
1989 MissingAttributeSubjectRulesRecoveryPoint::Comma, *
this)
1995 if (Tok.isNot(tok::identifier)) {
1996 createExpectedAttributeSubjectRulesTokenDiagnostic(
1997 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
1998 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
2002 const IdentifierInfo *II = Tok.getIdentifierInfo();
2003 if (!II->
isStr(
"apply_to")) {
2004 createExpectedAttributeSubjectRulesTokenDiagnostic(
2005 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
2006 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
2013 createExpectedAttributeSubjectRulesTokenDiagnostic(
2014 diag::err_expected, Attrs,
2015 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
2022 SourceLocation AnyLoc, LastMatchRuleEndLoc;
2023 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
2024 LastMatchRuleEndLoc)) {
2031 if (Tok.isNot(tok::eof)) {
2032 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
2041 if (Info->Action == PragmaAttributeInfo::Push)
2042 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
2044 for (ParsedAttr &Attribute : Attrs) {
2045 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
2053void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
2064 if (PushPop && PushPop->
isStr(
"pop")) {
2066 }
else if (PushPop && PushPop->
isStr(
"push")) {
2099 auto Toks = std::make_unique<Token[]>(1);
2100 Toks[0].startToken();
2101 Toks[0].setKind(tok::annot_pragma_vis);
2102 Toks[0].setLocation(VisLoc);
2103 Toks[0].setAnnotationEndLoc(EndLoc);
2104 Toks[0].setAnnotationValue(
2105 const_cast<void *
>(
static_cast<const void *
>(VisType)));
2106 PP.EnterTokenStream(std::move(Toks), 1,
true,
2128 StringRef SlotLabel;
2132 if (
Tok.
is(tok::numeric_constant)) {
2143 }
else if (
Tok.
is(tok::identifier)) {
2145 auto MapPack = [&](
const char *
Literal) {
2148 Alignment.
setKind(tok::numeric_constant);
2154 if (II->
isStr(
"show")) {
2174 if (II->
isStr(
"push")) {
2176 }
else if (II->
isStr(
"pop")) {
2184 if (
Tok.
is(tok::comma)) {
2187 if (
Tok.
is(tok::numeric_constant)) {
2192 }
else if (
Tok.
is(tok::identifier)) {
2196 if (
Tok.
is(tok::comma)) {
2199 if (
Tok.
isNot(tok::numeric_constant)) {
2244 Toks[0].startToken();
2245 Toks[0].setKind(tok::annot_pragma_pack);
2246 Toks[0].setLocation(PackLoc);
2247 Toks[0].setAnnotationEndLoc(RParenLoc);
2248 Toks[0].setAnnotationValue(
static_cast<void*
>(Info));
2249 PP.EnterTokenStream(Toks,
true,
2255void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
2257 Token &MSStructTok) {
2268 if (II->
isStr(
"on")) {
2272 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
2287 Toks[0].startToken();
2288 Toks[0].setKind(tok::annot_pragma_msstruct);
2290 Toks[0].setAnnotationEndLoc(EndLoc);
2291 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2293 PP.EnterTokenStream(Toks,
true,
2298void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
2300 Token &FirstToken) {
2308 PP.
Diag(
Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
2313 if (SecType->
isStr(
"bss"))
2315 else if (SecType->
isStr(
"data"))
2317 else if (SecType->
isStr(
"rodata"))
2319 else if (SecType->
isStr(
"relro"))
2321 else if (SecType->
isStr(
"text"))
2324 PP.
Diag(
Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
2336 std::string SecName;
2340 Actions.ActOnPragmaClangSection(PragmaLocation,
2357 if (
Tok.isNot(tok::identifier) ||
2358 !
Tok.getIdentifierInfo()->isStr(
"align")) {
2359 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_options_expected_align);
2366 if (
Tok.isNot(tok::l_paren)) {
2367 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_lparen) <<
"align";
2370 }
else if (
Tok.isNot(tok::equal)) {
2371 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_align_expected_equal)
2377 if (
Tok.isNot(tok::identifier)) {
2378 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_identifier)
2379 << (IsOptions ?
"options" :
"align");
2385 if (II->
isStr(
"native"))
2387 else if (II->
isStr(
"natural"))
2389 else if (II->
isStr(
"packed"))
2391 else if (II->
isStr(
"power"))
2393 else if (II->
isStr(
"mac68k"))
2395 else if (II->
isStr(
"reset"))
2398 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_align_invalid_option)
2405 if (
Tok.isNot(tok::r_paren)) {
2406 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_rparen) <<
"align";
2413 if (
Tok.isNot(tok::eod)) {
2414 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2415 << (IsOptions ?
"options" :
"align");
2421 Toks[0].startToken();
2422 Toks[0].setKind(tok::annot_pragma_align);
2424 Toks[0].setAnnotationEndLoc(EndLoc);
2425 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2427 PP.EnterTokenStream(Toks,
true,
2437void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
2439 Token &OptionsTok) {
2444void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
2467 if (
Tok.
is(tok::identifier)) {
2468 Identifiers.push_back(
Tok);
2479 if (
Tok.
is(tok::comma)) {
2484 if (
Tok.
is(tok::r_paren)) {
2502 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
2503 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
2512 2 * Identifiers.size());
2513 for (
unsigned i=0; i != Identifiers.size(); i++) {
2514 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
2516 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
2518 idTok = Identifiers[i];
2520 PP.EnterTokenStream(Toks,
true,
2539 bool HasAlias =
false;
2543 if (
Tok.
is(tok::equal)) {
2563 Token &pragmaUnusedTok = Toks[0];
2565 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2569 Toks[2] = AliasName;
2570 PP.EnterTokenStream(Toks,
true,
2575 Token &pragmaUnusedTok = Toks[0];
2577 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2581 PP.EnterTokenStream(Toks,
true,
2587void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2589 Token &RedefToken) {
2605 <<
"redefine_extname";
2620 Token &pragmaRedefTok = Toks[0];
2622 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2625 Toks[1] = RedefName;
2626 Toks[2] = AliasName;
2627 PP.EnterTokenStream(Toks,
true,
2631void PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2640 Toks[0].startToken();
2641 Toks[0].setKind(tok::annot_pragma_fp_contract);
2644 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2646 PP.EnterTokenStream(Toks,
true,
2650void PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2675 OpenCLExtState State;
2676 if (Pred->
isStr(
"enable")) {
2678 }
else if (Pred->
isStr(
"disable")) {
2680 }
else if (Pred->
isStr(
"begin"))
2682 else if (Pred->
isStr(
"end"))
2686 << Ext->
isStr(
"all");
2700 Info->second = State;
2703 Toks[0].startToken();
2704 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2705 Toks[0].setLocation(NameLoc);
2706 Toks[0].setAnnotationValue(
static_cast<void*
>(Info));
2707 Toks[0].setAnnotationEndLoc(StateLoc);
2708 PP.EnterTokenStream(Toks,
true,
2718template <diag::kind IgnoredDiag>
2719void PragmaNoSupportHandler<IgnoredDiag>::HandlePragma(
2722 PP.
Diag(FirstTok, IgnoredDiag);
2733void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
2742 Pragma.push_back(
Tok);
2744 if (
Tok.
is(StartTok)) {
2745 PP.
Diag(
Tok, UnexpectedDiag) << 0;
2746 unsigned InnerPragmaCnt = 1;
2747 while (InnerPragmaCnt != 0) {
2749 if (
Tok.
is(StartTok))
2751 else if (
Tok.
is(EndTok))
2761 Pragma.push_back(
Tok);
2763 auto Toks = std::make_unique<Token[]>(Pragma.size());
2764 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2765 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2777void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2783 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2784 <<
"pointers_to_members";
2791 <<
"pointers_to_members";
2797 if (Arg->
isStr(
"best_case")) {
2800 if (Arg->
isStr(
"full_generality")) {
2801 if (
Tok.
is(tok::comma)) {
2807 diag::err_pragma_pointers_to_members_unknown_kind)
2812 }
else if (
Tok.
is(tok::r_paren)) {
2819 <<
"full_generality";
2825 if (Arg->
isStr(
"single_inheritance")) {
2826 RepresentationMethod =
2828 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2829 RepresentationMethod =
2831 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2832 RepresentationMethod =
2836 diag::err_pragma_pointers_to_members_unknown_kind)
2845 << (Arg ? Arg->
getName() :
"full_generality");
2853 <<
"pointers_to_members";
2859 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2863 reinterpret_cast<void *
>(
static_cast<uintptr_t>(RepresentationMethod)));
2880 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2888 if (II->
isStr(
"push")) {
2892 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2898 }
else if (II->
isStr(
"pop")) {
2905 if (
Tok.
is(tok::r_paren)) {
2915 if (II && II->
isStr(
"off")) {
2918 }
else if (II && II->
isStr(
"on")) {
2921 }
else if (
Tok.
is(tok::numeric_constant) &&
2925 << 0 << 2 <<
"vtordisp";
2937 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2951 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2963 Token EoF, AnnotTok;
2967 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2973 TokenVector.push_back(
Tok);
2977 TokenVector.push_back(EoF);
2980 markAsReinjectedForRelexing(TokenVector);
2981 auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2982 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2984 std::pair<std::unique_ptr<Token[]>,
size_t>(std::move(TokenArray),
2985 TokenVector.size());
3001void PragmaFloatControlHandler::HandlePragma(
Preprocessor &PP,
3014 PP.
Diag(FloatControlLoc, diag::err_expected) << tok::l_paren;
3028 llvm::StringSwitch<PragmaFloatControlKind>(II->
getName())
3046 if (
Tok.
is(tok::r_paren))
3059 if (PushOnOff ==
"on")
3062 else if (PushOnOff ==
"off") {
3067 }
else if (PushOnOff ==
"push") {
3074 if (
Tok.
is(tok::comma)) {
3081 if (ExpectedPush ==
"push") {
3106 auto TokenArray = std::make_unique<Token[]>(1);
3107 TokenArray[0].startToken();
3108 TokenArray[0].setKind(tok::annot_pragma_float_control);
3109 TokenArray[0].setLocation(FloatControlLoc);
3110 TokenArray[0].setAnnotationEndLoc(EndLoc);
3113 TokenArray[0].setAnnotationValue(
reinterpret_cast<void *
>(
3114 static_cast<uintptr_t>((Action << 16) | (Kind & 0xFFFF))));
3115 PP.EnterTokenStream(std::move(TokenArray), 1,
3129void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
3135 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
3140 std::string NameString;
3142 "pragma detect_mismatch",
3147 std::string ValueString;
3173 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
3185void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
3191 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
3198 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
3205 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
3225 std::string ArgumentString;
3253 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
3258void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
3260 Token &FirstToken) {
3263 if (
Tok.
is(tok::eod)) {
3265 <<
"clang optimize" <<
true <<
"'on' or 'off'";
3276 if (II->
isStr(
"on")) {
3278 }
else if (!II->
isStr(
"off")) {
3291 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
3296struct TokFPAnnotValue {
3297 enum FlagValues { On, Off, Fast };
3299 std::optional<LangOptions::FPModeKind> ContractValue;
3300 std::optional<LangOptions::FPModeKind> ReassociateValue;
3301 std::optional<LangOptions::FPModeKind> ReciprocalValue;
3302 std::optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
3303 std::optional<LangOptions::FPEvalMethodKind> EvalMethodValue;
3321 while (
Tok.
is(tok::identifier)) {
3325 llvm::StringSwitch<std::optional<PragmaFPKind>>(OptionInfo->
getName())
3331 .Default(std::nullopt);
3334 <<
false << OptionInfo;
3345 bool isEvalMethodDouble =
3349 if (
Tok.
isNot(tok::identifier) && !isEvalMethodDouble) {
3352 <<
static_cast<int>(*FlagKind);
3358 AnnotValue->ContractValue =
3359 llvm::StringSwitch<std::optional<LangOptions::FPModeKind>>(
3364 .Default(std::nullopt);
3365 if (!AnnotValue->ContractValue) {
3372 : AnnotValue->ReciprocalValue;
3373 Value = llvm::StringSwitch<std::optional<LangOptions::FPModeKind>>(
3377 .Default(std::nullopt);
3384 AnnotValue->ExceptionsValue =
3385 llvm::StringSwitch<std::optional<LangOptions::FPExceptionModeKind>>(
3390 .Default(std::nullopt);
3391 if (!AnnotValue->ExceptionsValue) {
3397 AnnotValue->EvalMethodValue =
3398 llvm::StringSwitch<std::optional<LangOptions::FPEvalMethodKind>>(
3403 .Default(std::nullopt);
3404 if (!AnnotValue->EvalMethodValue) {
3428 FPTok.
setKind(tok::annot_pragma_fp);
3432 TokenList.push_back(FPTok);
3434 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3435 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3437 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3441void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(
Preprocessor &PP,
3460 llvm::StringSwitch<llvm::RoundingMode>(II->
getName())
3461 .Case(
"FE_TOWARDZERO", llvm::RoundingMode::TowardZero)
3462 .Case(
"FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven)
3463 .Case(
"FE_UPWARD", llvm::RoundingMode::TowardPositive)
3464 .Case(
"FE_DOWNWARD", llvm::RoundingMode::TowardNegative)
3465 .Case(
"FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway)
3466 .Case(
"FE_DYNAMIC", llvm::RoundingMode::Dynamic)
3467 .Default(llvm::RoundingMode::Invalid);
3468 if (RM == llvm::RoundingMode::Invalid) {
3476 <<
"STDC FENV_ROUND";
3485 Toks[0].startToken();
3486 Toks[0].setKind(tok::annot_pragma_fenv_round);
3489 Toks[0].setAnnotationValue(
3490 reinterpret_cast<void *
>(
static_cast<uintptr_t>(RM)));
3491 PP.EnterTokenStream(Toks,
true,
3495void Parser::HandlePragmaFP() {
3496 assert(Tok.is(tok::annot_pragma_fp));
3498 reinterpret_cast<TokFPAnnotValue *
>(Tok.getAnnotationValue());
3500 if (AnnotValue->ReassociateValue)
3501 Actions.ActOnPragmaFPValueChangingOption(
3505 if (AnnotValue->ReciprocalValue)
3506 Actions.ActOnPragmaFPValueChangingOption(
3510 if (AnnotValue->ContractValue)
3511 Actions.ActOnPragmaFPContract(Tok.getLocation(),
3512 *AnnotValue->ContractValue);
3513 if (AnnotValue->ExceptionsValue)
3514 Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
3515 *AnnotValue->ExceptionsValue);
3516 if (AnnotValue->EvalMethodValue)
3517 Actions.ActOnPragmaFPEvalMethod(Tok.getLocation(),
3518 *AnnotValue->EvalMethodValue);
3519 ConsumeAnnotationToken();
3524 Token Option,
bool ValueInParens,
3527 int OpenParens = ValueInParens ? 1 : 0;
3529 while (
Tok.isNot(tok::eod)) {
3530 if (
Tok.is(tok::l_paren))
3532 else if (
Tok.is(tok::r_paren)) {
3534 if (OpenParens == 0 && ValueInParens)
3542 if (ValueInParens) {
3544 if (
Tok.isNot(tok::r_paren)) {
3545 PP.
Diag(
Tok.getLocation(), diag::err_expected) << tok::r_paren;
3613void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
3628 while (
Tok.
is(tok::identifier)) {
3632 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
3633 .Case(
"vectorize",
true)
3634 .Case(
"interleave",
true)
3635 .Case(
"unroll",
true)
3636 .Case(
"distribute",
true)
3637 .Case(
"vectorize_predicate",
true)
3638 .Case(
"vectorize_width",
true)
3639 .Case(
"interleave_count",
true)
3640 .Case(
"unroll_count",
true)
3641 .Case(
"pipeline",
true)
3642 .Case(
"pipeline_initiation_interval",
true)
3646 <<
false << OptionInfo;
3666 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
3670 TokenList.push_back(LoopHintTok);
3679 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3680 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3682 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3707void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
3715 if (
Tok.
is(tok::eod)) {
3717 Info->PragmaName = PragmaName;
3718 Info->Option.startToken();
3728 bool ValueInParens =
Tok.
is(tok::l_paren);
3740 PP.
Diag(Info->Toks[0].getLocation(),
3741 diag::warn_pragma_unroll_cuda_value_in_parens);
3751 auto TokenArray = std::make_unique<Token[]>(1);
3752 TokenArray[0].startToken();
3753 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3754 TokenArray[0].setLocation(Introducer.
Loc);
3755 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
3756 TokenArray[0].setAnnotationValue(
static_cast<void *
>(Info));
3757 PP.EnterTokenStream(std::move(TokenArray), 1,
3761bool Parser::HandlePragmaMSFunction(StringRef PragmaName,
3763 Token FirstTok = Tok;
3765 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3769 bool SuggestIntrinH = !PP.isMacroDefined(
"__INTRIN_H");
3771 llvm::SmallVector<StringRef> NoBuiltins;
3772 while (Tok.is(tok::identifier)) {
3773 IdentifierInfo *II = Tok.getIdentifierInfo();
3775 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3776 << II << SuggestIntrinH;
3778 NoBuiltins.emplace_back(II->
getName());
3781 if (Tok.isNot(tok::comma))
3786 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3788 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3792 Actions.ActOnPragmaMSFunction(FirstTok.
getLocation(), NoBuiltins);
3796bool Parser::HandlePragmaMSOptimize(StringRef PragmaName,
3798 Token FirstTok = Tok;
3799 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3803 if (Tok.isNot(tok::string_literal)) {
3804 PP.Diag(PragmaLocation, diag::warn_pragma_expected_string) << PragmaName;
3812 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
3817 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_comma,
3821 if (Tok.is(tok::eof) || Tok.is(tok::r_paren)) {
3822 PP.Diag(PragmaLocation, diag::warn_pragma_missing_argument)
3823 << PragmaName <<
true <<
"'on' or 'off'";
3826 IdentifierInfo *II = Tok.getIdentifierInfo();
3827 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3828 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3829 << PP.getSpelling(Tok) << PragmaName <<
true
3833 bool IsOn = II->
isStr(
"on");
3836 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3841 if (!OptimizationList->
getString().empty()) {
3842 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3843 << OptimizationList->
getString() << PragmaName <<
true
3848 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3852 Actions.ActOnPragmaMSOptimize(FirstTok.
getLocation(), IsOn);
3869bool Parser::HandlePragmaMSIntrinsic(StringRef PragmaName,
3871 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3875 bool SuggestIntrinH = !PP.isMacroDefined(
"__INTRIN_H");
3877 while (Tok.is(tok::identifier)) {
3878 IdentifierInfo *II = Tok.getIdentifierInfo();
3880 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3881 << II << SuggestIntrinH;
3883 DeclarationNameInfo NameInfo(II, Tok.getLocation());
3886 Actions.LookupName(
Previous, Actions.getCurScope(),
3889 Actions.LazilyCreateBuiltin(II, II->
getBuiltinID(), Actions.getCurScope(),
3890 true, Tok.getLocation());
3892 if (Tok.isNot(tok::comma))
3896 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3900 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3906void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3912 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3914 diag::warn_pragma_force_cuda_host_device_bad_arg);
3918 if (Info->
isStr(
"begin"))
3919 Actions.CUDA().PushForceHostDevice();
3920 else if (!Actions.CUDA().PopForceHostDevice())
3922 diag::err_pragma_cannot_end_force_cuda_host_device);
3925 if (!
Tok.
is(tok::eod))
3927 diag::warn_pragma_force_cuda_host_device_bad_arg);
3957void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3959 Token &FirstToken) {
3963 PragmaAttributeInfo(AttributesForPragmaAttribute);
3966 if (
Tok.
is(tok::identifier)) {
3968 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3969 Info->Namespace = II;
3972 if (!
Tok.
is(tok::period)) {
3981 if (!
Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3983 diag::err_pragma_attribute_expected_push_pop_paren);
3988 if (
Tok.
is(tok::l_paren)) {
3989 if (Info->Namespace) {
3991 diag::err_pragma_attribute_namespace_on_attribute);
3993 diag::note_pragma_attribute_namespace_on_attribute);
3996 Info->Action = PragmaAttributeInfo::Attribute;
3999 if (II->
isStr(
"push"))
4000 Info->Action = PragmaAttributeInfo::Push;
4001 else if (II->
isStr(
"pop"))
4002 Info->Action = PragmaAttributeInfo::Pop;
4013 if ((Info->Action == PragmaAttributeInfo::Push &&
Tok.
isNot(tok::eod)) ||
4014 Info->Action == PragmaAttributeInfo::Attribute) {
4025 if (
Tok.
is(tok::l_paren))
4027 else if (
Tok.
is(tok::r_paren)) {
4029 if (OpenParens == 0)
4033 AttributeTokens.push_back(
Tok);
4037 if (AttributeTokens.empty()) {
4053 AttributeTokens.push_back(EOFTok);
4055 markAsReinjectedForRelexing(AttributeTokens);
4062 <<
"clang attribute";
4065 auto TokenArray = std::make_unique<Token[]>(1);
4066 TokenArray[0].startToken();
4067 TokenArray[0].setKind(tok::annot_pragma_attribute);
4068 TokenArray[0].setLocation(FirstToken.
getLocation());
4069 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
4070 TokenArray[0].setAnnotationValue(
static_cast<void *
>(Info));
4071 PP.EnterTokenStream(std::move(TokenArray), 1,
4076void PragmaMaxTokensHereHandler::HandlePragma(
Preprocessor &PP,
4080 if (
Tok.
is(tok::eod)) {
4082 <<
"clang max_tokens_here" <<
true <<
"integer";
4088 if (
Tok.
isNot(tok::numeric_constant) ||
4091 <<
"clang max_tokens_here";
4097 <<
"clang max_tokens_here";
4102 PP.
Diag(Loc, diag::warn_max_tokens)
4108void PragmaMaxTokensTotalHandler::HandlePragma(
Preprocessor &PP,
4112 if (
Tok.
is(tok::eod)) {
4114 <<
"clang max_tokens_total" <<
true <<
"integer";
4120 if (
Tok.
isNot(tok::numeric_constant) ||
4123 <<
"clang max_tokens_total";
4129 <<
"clang max_tokens_total";
4141 Token &FirstToken) {
4146 if (!II || !II->
isStr(
"intrinsic")) {
4154 if (!II || !(II->
isStr(
"vector") || II->
isStr(
"sifive_vector") ||
4155 II->
isStr(
"andes_vector"))) {
4158 <<
"'vector', 'sifive_vector' or 'andes_vector'";
4165 <<
"clang riscv intrinsic";
4169 if (II->
isStr(
"vector"))
4170 Actions.RISCV().DeclareRVVBuiltins =
true;
4171 else if (II->
isStr(
"sifive_vector"))
4172 Actions.RISCV().DeclareSiFiveVectorBuiltins =
true;
4173 else if (II->
isStr(
"andes_vector"))
4174 Actions.RISCV().DeclareAndesVectorBuiltins =
true;
Defines the clang::ASTContext interface.
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, bool IsOptions)
static void diagnoseUnknownAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, StringRef SubRuleName, SourceLocation SubRuleLoc)
static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, Token Option, bool ValueInParens, PragmaLoopHintInfo &Info)
Parses loop or unroll pragma hint value and fills in Info.
static void diagnoseExpectedAttributeSubjectSubRule(Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName, SourceLocation SubRuleLoc)
static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule)
static StringRef getIdentifier(const Token &Tok)
static std::string PragmaLoopHintString(Token PragmaName, Token Option)
Defines the clang::Preprocessor interface.
ArrayRef< SVal > ValueList
@ NotForRedeclaration
The lookup is a reference to this name that is not for the purpose of redeclaring the name.
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis functions specific to RISC-V.
Kind getParsedKind() const
static CharSourceRange getCharRange(SourceRange R)
A little helper class used to produce diagnostics.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
ExprDependence getDependence() const
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
@ FEM_Extended
Use extended type for fp arithmetic.
@ FEM_Double
Use the type double for fp arithmetic.
@ FEM_Source
Use the declared type for fp arithmetic.
ComplexRangeKind
Controls the various implementations for complex multiplication and.
@ CX_Full
Implementation of complex division and multiplication using a call to runtime library functions(gener...
@ CX_Basic
Implementation of complex division and multiplication using algebraic formulas at source precision.
PragmaMSPointersToMembersKind
@ PPTMK_FullGeneralityMultipleInheritance
@ PPTMK_FullGeneralityVirtualInheritance
@ PPTMK_FullGeneralitySingleInheritance
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, StringRef Str)
Callback invoked when a #pragma comment directive is read.
virtual void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State)
Called when an OpenCL extension is either disabled or enabled with a pragma.
virtual void PragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
Callback invoked when a #pragma detect_mismatch directive is read.
ParsedAttr - Represents a syntactic attribute.
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
ParseStringLiteralExpression - This handles the various token types that form string literals,...
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies)
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const Token & getCurToken() const
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
friend class BalancedDelimiterTracker
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
PPCallbacks * getPPCallbacks() const
void overrideMaxTokens(unsigned Value, SourceLocation Loc)
void Lex(Token &Result)
Lex the next token for this preprocessor.
SourceRange DiscardUntilEndOfDirective()
Read and discard all tokens remaining on the current line until the tok::eod token is found.
bool LexOnOffSwitch(tok::OnOffSwitch &Result)
Lex an on-off-switch (C99 6.10.6p2) and verify that it is followed by EOD.
unsigned getTokenCount() const
Get the number of tokens processed so far.
const TargetInfo & getTargetInfo() const
bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)
Parses a simple integer literal to get its numeric value.
void LexUnexpandedToken(Token &Result)
Just like Lex, but disables macro expansion of identifier tokens.
llvm::BumpPtrAllocator & getPreprocessorAllocator()
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
bool LexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Lex a string literal, which may be the concatenation of multiple string literals and may even come fr...
@ CompoundStmtScope
This is a compound statement scope.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ DeclScope
This is a scope that can contain a declaration.
Sema - This implements semantic analysis and AST building for C.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
unsigned getLength() const
StringRef getString() const
unsigned getCharByteWidth() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool hasStrictFP() const
Determine whether constrained floating point is supported on this target.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
void setLiteralData(const char *Ptr)
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
void setAnnotationEndLoc(SourceLocation L)
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setLength(unsigned Len)
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setLocation(SourceLocation L)
bool isNot(tok::TokenKind K) const
void setAnnotationValue(void *val)
void startToken()
Reset all flags to cleared.
Defines the clang::TargetInfo interface.
SubjectMatchRule
A list of all the recognized kinds of attributes.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
llvm::DenseMap< int, SourceRange > ParsedSubjectMatchRuleSet
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
@ Ignored
Do not present this diagnostic, ignore it.
@ FixIt
Parse and apply any fixits to the source.
const Regex Rule("(.+)/(.+)\\.framework/")
bool Pop(InterpState &S, CodePtr OpPC)
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ActionResult< Stmt * > StmtResult
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Loop optimization hint for loop and unroll pragmas.
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc
Describes how and where the pragma was introduced.
PragmaMsStackAction Action