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;
1422 auto IsLoopHint = llvm::StringSwitch<bool>(PragmaNameInfo->
getName())
1423 .Cases(
"unroll",
"nounroll",
"unroll_and_jam",
1424 "nounroll_and_jam",
true)
1427 if (Toks.empty() && IsLoopHint) {
1428 ConsumeAnnotationToken();
1435 assert(!Toks.empty() &&
1436 "PragmaLoopHintInfo::Toks must contain at least one token.");
1439 bool OptionUnroll =
false;
1440 bool OptionUnrollAndJam =
false;
1441 bool OptionDistribute =
false;
1442 bool OptionPipelineDisabled =
false;
1443 bool StateOption =
false;
1445 OptionUnroll = OptionInfo->
isStr(
"unroll");
1446 OptionUnrollAndJam = OptionInfo->
isStr(
"unroll_and_jam");
1447 OptionDistribute = OptionInfo->
isStr(
"distribute");
1448 OptionPipelineDisabled = OptionInfo->
isStr(
"pipeline");
1449 StateOption = llvm::StringSwitch<bool>(OptionInfo->
getName())
1450 .Case(
"vectorize",
true)
1451 .Case(
"interleave",
true)
1452 .Case(
"vectorize_predicate",
true)
1454 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1455 OptionPipelineDisabled;
1458 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1459 !OptionDistribute && !OptionPipelineDisabled;
1461 if (Toks[0].
is(tok::eof)) {
1462 ConsumeAnnotationToken();
1463 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1465 << (OptionUnroll || OptionUnrollAndJam)
1472 ConsumeAnnotationToken();
1473 SourceLocation StateLoc = Toks[0].getLocation();
1474 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1476 bool Valid = StateInfo &&
1477 llvm::StringSwitch<bool>(StateInfo->
getName())
1478 .Case(
"disable",
true)
1479 .Case(
"enable", !OptionPipelineDisabled)
1480 .Case(
"full", OptionUnroll || OptionUnrollAndJam)
1481 .Case(
"assume_safety", AssumeSafetyArg)
1484 if (OptionPipelineDisabled) {
1485 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1487 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1488 << (OptionUnroll || OptionUnrollAndJam)
1493 if (Toks.size() > 2)
1494 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1496 Hint.
StateLoc =
new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1497 }
else if (OptionInfo && OptionInfo->
getName() ==
"vectorize_width") {
1498 PP.EnterTokenStream(Toks,
false,
1500 ConsumeAnnotationToken();
1502 SourceLocation StateLoc = Toks[0].getLocation();
1503 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1504 StringRef IsScalableStr = StateInfo ? StateInfo->
getName() :
"";
1507 if (IsScalableStr ==
"scalable" || IsScalableStr ==
"fixed") {
1510 if (Toks.size() > 2) {
1511 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1513 while (Tok.isNot(tok::eof))
1517 Hint.
StateLoc =
new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1524 if (R.
isInvalid() && !Tok.is(tok::comma))
1525 Diag(Toks[0].getLocation(),
1526 diag::note_pragma_loop_invalid_vectorize_option);
1528 bool Arg2Error =
false;
1529 if (Tok.is(tok::comma)) {
1532 StateInfo = Tok.getIdentifierInfo();
1533 IsScalableStr = StateInfo->
getName();
1535 if (IsScalableStr !=
"scalable" && IsScalableStr !=
"fixed") {
1536 Diag(Tok.getLocation(),
1537 diag::err_pragma_loop_invalid_vectorize_option);
1541 new (Actions.Context) IdentifierLoc(StateLoc, StateInfo);
1548 if (Tok.isNot(tok::eof)) {
1549 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1551 while (Tok.isNot(tok::eof))
1558 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation(),
1567 PP.EnterTokenStream(Toks,
false,
1569 ConsumeAnnotationToken();
1574 if (Tok.isNot(tok::eof)) {
1575 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1577 while (Tok.isNot(tok::eof))
1584 Actions.CheckLoopHintExpr(R.
get(), Toks[0].getLocation(),
1593 Info->
Toks.back().getLocation());
1598struct PragmaAttributeInfo {
1599 enum ActionType { Push,
Pop, Attribute };
1600 ParsedAttributes &Attributes;
1602 const IdentifierInfo *
Namespace =
nullptr;
1603 ArrayRef<Token> Tokens;
1605 PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1608#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1613 if (
Tok.is(tok::identifier))
1614 return Tok.getIdentifierInfo()->getName();
1622 using namespace attr;
1624#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1627#include "clang/Basic/AttrSubMatchRulesList.inc"
1629 llvm_unreachable(
"Invalid attribute subject match rule");
1637 PRef.
Diag(SubRuleLoc,
1638 diag::err_pragma_attribute_expected_subject_sub_identifier)
1640 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1651 PRef.
Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1652 << SubRuleName << PrimaryRuleName;
1653 if (
const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1659bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1667 if (AnyParens.expectAndConsume())
1675 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1678 std::pair<std::optional<attr::SubjectMatchRule>,
1679 std::optional<attr::SubjectMatchRule> (*)(StringRef,
bool)>
1680 Rule = isAttributeSubjectMatchRule(Name);
1682 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1690 if (
Parens.expectAndConsume())
1692 }
else if (
Parens.consumeOpen()) {
1693 if (!SubjectMatchRules
1695 std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1697 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1700 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1701 LastMatchRuleEndLoc = RuleLoc;
1707 if (SubRuleName.empty()) {
1713 if (SubRuleName ==
"unless") {
1716 if (
Parens.expectAndConsume())
1719 if (SubRuleName.empty()) {
1724 auto SubRuleOrNone =
Rule.second(SubRuleName,
true);
1725 if (!SubRuleOrNone) {
1726 std::string SubRuleUnlessName =
"unless(" + SubRuleName.str() +
")";
1728 SubRuleUnlessName, SubRuleLoc);
1731 SubRule = *SubRuleOrNone;
1733 if (
Parens.consumeClose())
1736 auto SubRuleOrNone =
Rule.second(SubRuleName,
false);
1737 if (!SubRuleOrNone) {
1739 SubRuleName, Tok.getLocation());
1742 SubRule = *SubRuleOrNone;
1745 SourceLocation RuleEndLoc = Tok.getLocation();
1746 LastMatchRuleEndLoc = RuleEndLoc;
1747 if (
Parens.consumeClose())
1749 if (!SubjectMatchRules
1750 .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1752 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1755 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1761 if (AnyParens.consumeClose())
1770enum class MissingAttributeSubjectRulesRecoveryPoint {
1778MissingAttributeSubjectRulesRecoveryPoint
1779getAttributeSubjectRulesRecoveryPointForToken(
const Token &
Tok) {
1781 if (II->
isStr(
"apply_to"))
1782 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1783 if (II->
isStr(
"any"))
1784 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1786 if (
Tok.
is(tok::equal))
1787 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1788 return MissingAttributeSubjectRulesRecoveryPoint::None;
1796 MissingAttributeSubjectRulesRecoveryPoint Point,
Parser &PRef) {
1802 MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1803 getAttributeSubjectRulesRecoveryPointForToken(PRef.
getCurToken());
1804 if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1806 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1807 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1808 FixIt +=
"apply_to";
1809 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1810 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1813 if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1820 Attribute.getMatchRules(PRef.
getLangOpts(), MatchRules);
1822 for (
const auto &Rule : MatchRules) {
1827 IsSupported[
Rule.first] =
true;
1829 IsMatchRuleAvailable &= IsSupported;
1831 if (IsMatchRuleAvailable.count() == 0) {
1837 bool NeedsComma =
false;
1839 if (!IsMatchRuleAvailable[I])
1853 if (FixItRange.getBegin() == FixItRange.getEnd())
1863void Parser::HandlePragmaAttribute() {
1864 assert(Tok.is(tok::annot_pragma_attribute) &&
1865 "Expected #pragma attribute annotation token");
1866 SourceLocation PragmaLoc = Tok.getLocation();
1867 auto *Info =
static_cast<PragmaAttributeInfo *
>(Tok.getAnnotationValue());
1868 if (Info->Action == PragmaAttributeInfo::Pop) {
1869 ConsumeAnnotationToken();
1870 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1874 assert((Info->Action == PragmaAttributeInfo::Push ||
1875 Info->Action == PragmaAttributeInfo::Attribute) &&
1876 "Unexpected #pragma attribute command");
1878 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1879 ConsumeAnnotationToken();
1880 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1884 PP.EnterTokenStream(Info->Tokens,
false,
1886 ConsumeAnnotationToken();
1888 ParsedAttributes &Attrs = Info->Attributes;
1891 auto SkipToEnd = [
this]() {
1896 if ((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1897 Tok.isRegularKeywordAttribute()) {
1899 ParseCXX11AttributeSpecifier(Attrs);
1900 }
else if (Tok.is(tok::kw___attribute)) {
1902 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1905 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"("))
1910 if (Tok.is(tok::code_completion)) {
1913 Actions.CodeCompletion().CodeCompleteAttribute(
1920 if (Tok.isNot(tok::identifier)) {
1921 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1925 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1928 if (Tok.isNot(tok::l_paren))
1929 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1930 ParsedAttr::Form::GNU());
1932 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs,
nullptr,
1935 ParsedAttr::Form::GNU(),
1939 if (ExpectAndConsume(tok::r_paren))
1941 if (ExpectAndConsume(tok::r_paren))
1943 }
else if (Tok.is(tok::kw___declspec)) {
1944 ParseMicrosoftDeclSpecs(Attrs);
1946 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1947 if (Tok.getIdentifierInfo()) {
1951 Tok.getIdentifierInfo(),
nullptr,
1953 SourceLocation InsertStartLoc = Tok.getLocation();
1955 if (Tok.is(tok::l_paren)) {
1958 if (Tok.isNot(tok::r_paren))
1961 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1970 if (Attrs.
empty() || Attrs.
begin()->isInvalid()) {
1975 for (
const ParsedAttr &Attribute : Attrs) {
1976 if (!Attribute.isSupportedByPragmaAttribute()) {
1977 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1986 createExpectedAttributeSubjectRulesTokenDiagnostic(
1987 diag::err_expected, Attrs,
1988 MissingAttributeSubjectRulesRecoveryPoint::Comma, *
this)
1994 if (Tok.isNot(tok::identifier)) {
1995 createExpectedAttributeSubjectRulesTokenDiagnostic(
1996 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
1997 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
2001 const IdentifierInfo *II = Tok.getIdentifierInfo();
2002 if (!II->
isStr(
"apply_to")) {
2003 createExpectedAttributeSubjectRulesTokenDiagnostic(
2004 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
2005 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *
this);
2012 createExpectedAttributeSubjectRulesTokenDiagnostic(
2013 diag::err_expected, Attrs,
2014 MissingAttributeSubjectRulesRecoveryPoint::Equals, *
this)
2021 SourceLocation AnyLoc, LastMatchRuleEndLoc;
2022 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
2023 LastMatchRuleEndLoc)) {
2030 if (Tok.isNot(tok::eof)) {
2031 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
2040 if (Info->Action == PragmaAttributeInfo::Push)
2041 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
2043 for (ParsedAttr &Attribute : Attrs) {
2044 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
2052void PragmaGCCVisibilityHandler::HandlePragma(
Preprocessor &PP,
2063 if (PushPop && PushPop->
isStr(
"pop")) {
2065 }
else if (PushPop && PushPop->
isStr(
"push")) {
2098 auto Toks = std::make_unique<Token[]>(1);
2099 Toks[0].startToken();
2100 Toks[0].setKind(tok::annot_pragma_vis);
2101 Toks[0].setLocation(VisLoc);
2102 Toks[0].setAnnotationEndLoc(EndLoc);
2103 Toks[0].setAnnotationValue(
2104 const_cast<void *
>(
static_cast<const void *
>(VisType)));
2105 PP.EnterTokenStream(std::move(Toks), 1,
true,
2127 StringRef SlotLabel;
2131 if (
Tok.
is(tok::numeric_constant)) {
2142 }
else if (
Tok.
is(tok::identifier)) {
2144 auto MapPack = [&](
const char *
Literal) {
2147 Alignment.
setKind(tok::numeric_constant);
2153 if (II->
isStr(
"show")) {
2173 if (II->
isStr(
"push")) {
2175 }
else if (II->
isStr(
"pop")) {
2183 if (
Tok.
is(tok::comma)) {
2186 if (
Tok.
is(tok::numeric_constant)) {
2191 }
else if (
Tok.
is(tok::identifier)) {
2195 if (
Tok.
is(tok::comma)) {
2198 if (
Tok.
isNot(tok::numeric_constant)) {
2243 Toks[0].startToken();
2244 Toks[0].setKind(tok::annot_pragma_pack);
2245 Toks[0].setLocation(PackLoc);
2246 Toks[0].setAnnotationEndLoc(RParenLoc);
2247 Toks[0].setAnnotationValue(
static_cast<void*
>(Info));
2248 PP.EnterTokenStream(Toks,
true,
2254void PragmaMSStructHandler::HandlePragma(
Preprocessor &PP,
2256 Token &MSStructTok) {
2267 if (II->
isStr(
"on")) {
2271 else if (II->
isStr(
"off") || II->
isStr(
"reset"))
2286 Toks[0].startToken();
2287 Toks[0].setKind(tok::annot_pragma_msstruct);
2289 Toks[0].setAnnotationEndLoc(EndLoc);
2290 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2292 PP.EnterTokenStream(Toks,
true,
2297void PragmaClangSectionHandler::HandlePragma(
Preprocessor &PP,
2299 Token &FirstToken) {
2307 PP.
Diag(
Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
2312 if (SecType->
isStr(
"bss"))
2314 else if (SecType->
isStr(
"data"))
2316 else if (SecType->
isStr(
"rodata"))
2318 else if (SecType->
isStr(
"relro"))
2320 else if (SecType->
isStr(
"text"))
2323 PP.
Diag(
Tok.
getLocation(), diag::err_pragma_expected_clang_section_name) <<
"clang section";
2335 std::string SecName;
2339 Actions.ActOnPragmaClangSection(PragmaLocation,
2356 if (
Tok.isNot(tok::identifier) ||
2357 !
Tok.getIdentifierInfo()->isStr(
"align")) {
2358 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_options_expected_align);
2365 if (
Tok.isNot(tok::l_paren)) {
2366 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_lparen) <<
"align";
2369 }
else if (
Tok.isNot(tok::equal)) {
2370 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_align_expected_equal)
2376 if (
Tok.isNot(tok::identifier)) {
2377 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_identifier)
2378 << (IsOptions ?
"options" :
"align");
2384 if (II->
isStr(
"native"))
2386 else if (II->
isStr(
"natural"))
2388 else if (II->
isStr(
"packed"))
2390 else if (II->
isStr(
"power"))
2392 else if (II->
isStr(
"mac68k"))
2394 else if (II->
isStr(
"reset"))
2397 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_align_invalid_option)
2404 if (
Tok.isNot(tok::r_paren)) {
2405 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_expected_rparen) <<
"align";
2412 if (
Tok.isNot(tok::eod)) {
2413 PP.
Diag(
Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2414 << (IsOptions ?
"options" :
"align");
2420 Toks[0].startToken();
2421 Toks[0].setKind(tok::annot_pragma_align);
2423 Toks[0].setAnnotationEndLoc(EndLoc);
2424 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2426 PP.EnterTokenStream(Toks,
true,
2436void PragmaOptionsHandler::HandlePragma(
Preprocessor &PP,
2438 Token &OptionsTok) {
2443void PragmaUnusedHandler::HandlePragma(
Preprocessor &PP,
2466 if (
Tok.
is(tok::identifier)) {
2467 Identifiers.push_back(
Tok);
2478 if (
Tok.
is(tok::comma)) {
2483 if (
Tok.
is(tok::r_paren)) {
2501 assert(RParenLoc.
isValid() &&
"Valid '#pragma unused' must have ')'");
2502 assert(!Identifiers.empty() &&
"Valid '#pragma unused' must have arguments");
2511 2 * Identifiers.size());
2512 for (
unsigned i=0; i != Identifiers.size(); i++) {
2513 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
2515 pragmaUnusedTok.
setKind(tok::annot_pragma_unused);
2517 idTok = Identifiers[i];
2519 PP.EnterTokenStream(Toks,
true,
2538 bool HasAlias =
false;
2542 if (
Tok.
is(tok::equal)) {
2562 Token &pragmaUnusedTok = Toks[0];
2564 pragmaUnusedTok.
setKind(tok::annot_pragma_weakalias);
2568 Toks[2] = AliasName;
2569 PP.EnterTokenStream(Toks,
true,
2574 Token &pragmaUnusedTok = Toks[0];
2576 pragmaUnusedTok.
setKind(tok::annot_pragma_weak);
2580 PP.EnterTokenStream(Toks,
true,
2586void PragmaRedefineExtnameHandler::HandlePragma(
Preprocessor &PP,
2588 Token &RedefToken) {
2604 <<
"redefine_extname";
2619 Token &pragmaRedefTok = Toks[0];
2621 pragmaRedefTok.
setKind(tok::annot_pragma_redefine_extname);
2624 Toks[1] = RedefName;
2625 Toks[2] = AliasName;
2626 PP.EnterTokenStream(Toks,
true,
2630void PragmaFPContractHandler::HandlePragma(
Preprocessor &PP,
2639 Toks[0].startToken();
2640 Toks[0].setKind(tok::annot_pragma_fp_contract);
2643 Toks[0].setAnnotationValue(
reinterpret_cast<void*
>(
2645 PP.EnterTokenStream(Toks,
true,
2649void PragmaOpenCLExtensionHandler::HandlePragma(
Preprocessor &PP,
2674 OpenCLExtState State;
2675 if (Pred->
isStr(
"enable")) {
2677 }
else if (Pred->
isStr(
"disable")) {
2679 }
else if (Pred->
isStr(
"begin"))
2681 else if (Pred->
isStr(
"end"))
2685 << Ext->
isStr(
"all");
2699 Info->second = State;
2702 Toks[0].startToken();
2703 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2704 Toks[0].setLocation(NameLoc);
2705 Toks[0].setAnnotationValue(
static_cast<void*
>(Info));
2706 Toks[0].setAnnotationEndLoc(StateLoc);
2707 PP.EnterTokenStream(Toks,
true,
2717template <diag::kind IgnoredDiag>
2718void PragmaNoSupportHandler<IgnoredDiag>::HandlePragma(
2721 PP.
Diag(FirstTok, IgnoredDiag);
2732void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
2741 Pragma.push_back(
Tok);
2743 if (
Tok.
is(StartTok)) {
2744 PP.
Diag(
Tok, UnexpectedDiag) << 0;
2745 unsigned InnerPragmaCnt = 1;
2746 while (InnerPragmaCnt != 0) {
2748 if (
Tok.
is(StartTok))
2750 else if (
Tok.
is(EndTok))
2760 Pragma.push_back(
Tok);
2762 auto Toks = std::make_unique<Token[]>(Pragma.size());
2763 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2764 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2776void PragmaMSPointersToMembers::HandlePragma(
Preprocessor &PP,
2782 PP.
Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2783 <<
"pointers_to_members";
2790 <<
"pointers_to_members";
2796 if (Arg->
isStr(
"best_case")) {
2799 if (Arg->
isStr(
"full_generality")) {
2800 if (
Tok.
is(tok::comma)) {
2806 diag::err_pragma_pointers_to_members_unknown_kind)
2811 }
else if (
Tok.
is(tok::r_paren)) {
2818 <<
"full_generality";
2824 if (Arg->
isStr(
"single_inheritance")) {
2825 RepresentationMethod =
2827 }
else if (Arg->
isStr(
"multiple_inheritance")) {
2828 RepresentationMethod =
2830 }
else if (Arg->
isStr(
"virtual_inheritance")) {
2831 RepresentationMethod =
2835 diag::err_pragma_pointers_to_members_unknown_kind)
2844 << (Arg ? Arg->
getName() :
"full_generality");
2852 <<
"pointers_to_members";
2858 AnnotTok.
setKind(tok::annot_pragma_ms_pointers_to_members);
2862 reinterpret_cast<void *
>(
static_cast<uintptr_t>(RepresentationMethod)));
2879 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) <<
"vtordisp";
2887 if (II->
isStr(
"push")) {
2891 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_punc) <<
"vtordisp";
2897 }
else if (II->
isStr(
"pop")) {
2904 if (
Tok.
is(tok::r_paren)) {
2914 if (II && II->
isStr(
"off")) {
2917 }
else if (II && II->
isStr(
"on")) {
2920 }
else if (
Tok.
is(tok::numeric_constant) &&
2924 << 0 << 2 <<
"vtordisp";
2936 PP.
Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) <<
"vtordisp";
2950 AnnotTok.
setKind(tok::annot_pragma_ms_vtordisp);
2962 Token EoF, AnnotTok;
2966 AnnotTok.
setKind(tok::annot_pragma_ms_pragma);
2972 TokenVector.push_back(
Tok);
2976 TokenVector.push_back(EoF);
2979 markAsReinjectedForRelexing(TokenVector);
2980 auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2981 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2983 std::pair<std::unique_ptr<Token[]>,
size_t>(std::move(TokenArray),
2984 TokenVector.size());
3000void PragmaFloatControlHandler::HandlePragma(
Preprocessor &PP,
3013 PP.
Diag(FloatControlLoc, diag::err_expected) << tok::l_paren;
3027 llvm::StringSwitch<PragmaFloatControlKind>(II->
getName())
3045 if (
Tok.
is(tok::r_paren))
3058 if (PushOnOff ==
"on")
3061 else if (PushOnOff ==
"off") {
3066 }
else if (PushOnOff ==
"push") {
3073 if (
Tok.
is(tok::comma)) {
3080 if (ExpectedPush ==
"push") {
3105 auto TokenArray = std::make_unique<Token[]>(1);
3106 TokenArray[0].startToken();
3107 TokenArray[0].setKind(tok::annot_pragma_float_control);
3108 TokenArray[0].setLocation(FloatControlLoc);
3109 TokenArray[0].setAnnotationEndLoc(EndLoc);
3112 TokenArray[0].setAnnotationValue(
reinterpret_cast<void *
>(
3113 static_cast<uintptr_t>((Action << 16) | (Kind & 0xFFFF))));
3114 PP.EnterTokenStream(std::move(TokenArray), 1,
3128void PragmaDetectMismatchHandler::HandlePragma(
Preprocessor &PP,
3134 PP.
Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
3139 std::string NameString;
3141 "pragma detect_mismatch",
3146 std::string ValueString;
3172 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
3184void PragmaCommentHandler::HandlePragma(
Preprocessor &PP,
3190 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
3197 PP.
Diag(CommentLoc, diag::err_pragma_comment_malformed);
3204 llvm::StringSwitch<PragmaMSCommentKind>(II->
getName())
3224 std::string ArgumentString;
3252 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
3257void PragmaOptimizeHandler::HandlePragma(
Preprocessor &PP,
3259 Token &FirstToken) {
3262 if (
Tok.
is(tok::eod)) {
3264 <<
"clang optimize" <<
true <<
"'on' or 'off'";
3275 if (II->
isStr(
"on")) {
3277 }
else if (!II->
isStr(
"off")) {
3290 Actions.ActOnPragmaOptimize(IsOn, FirstToken.
getLocation());
3295struct TokFPAnnotValue {
3296 enum FlagValues { On, Off, Fast };
3298 std::optional<LangOptions::FPModeKind> ContractValue;
3299 std::optional<LangOptions::FPModeKind> ReassociateValue;
3300 std::optional<LangOptions::FPModeKind> ReciprocalValue;
3301 std::optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
3302 std::optional<LangOptions::FPEvalMethodKind> EvalMethodValue;
3320 while (
Tok.
is(tok::identifier)) {
3324 llvm::StringSwitch<std::optional<PragmaFPKind>>(OptionInfo->
getName())
3330 .Default(std::nullopt);
3333 <<
false << OptionInfo;
3344 bool isEvalMethodDouble =
3348 if (
Tok.
isNot(tok::identifier) && !isEvalMethodDouble) {
3351 <<
static_cast<int>(*FlagKind);
3357 AnnotValue->ContractValue =
3358 llvm::StringSwitch<std::optional<LangOptions::FPModeKind>>(
3363 .Default(std::nullopt);
3364 if (!AnnotValue->ContractValue) {
3371 : AnnotValue->ReciprocalValue;
3372 Value = llvm::StringSwitch<std::optional<LangOptions::FPModeKind>>(
3376 .Default(std::nullopt);
3383 AnnotValue->ExceptionsValue =
3384 llvm::StringSwitch<std::optional<LangOptions::FPExceptionModeKind>>(
3389 .Default(std::nullopt);
3390 if (!AnnotValue->ExceptionsValue) {
3396 AnnotValue->EvalMethodValue =
3397 llvm::StringSwitch<std::optional<LangOptions::FPEvalMethodKind>>(
3402 .Default(std::nullopt);
3403 if (!AnnotValue->EvalMethodValue) {
3427 FPTok.
setKind(tok::annot_pragma_fp);
3431 TokenList.push_back(FPTok);
3433 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3434 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3436 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3440void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(
Preprocessor &PP,
3459 llvm::StringSwitch<llvm::RoundingMode>(II->
getName())
3460 .Case(
"FE_TOWARDZERO", llvm::RoundingMode::TowardZero)
3461 .Case(
"FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven)
3462 .Case(
"FE_UPWARD", llvm::RoundingMode::TowardPositive)
3463 .Case(
"FE_DOWNWARD", llvm::RoundingMode::TowardNegative)
3464 .Case(
"FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway)
3465 .Case(
"FE_DYNAMIC", llvm::RoundingMode::Dynamic)
3466 .Default(llvm::RoundingMode::Invalid);
3467 if (RM == llvm::RoundingMode::Invalid) {
3475 <<
"STDC FENV_ROUND";
3484 Toks[0].startToken();
3485 Toks[0].setKind(tok::annot_pragma_fenv_round);
3488 Toks[0].setAnnotationValue(
3489 reinterpret_cast<void *
>(
static_cast<uintptr_t>(RM)));
3490 PP.EnterTokenStream(Toks,
true,
3494void Parser::HandlePragmaFP() {
3495 assert(Tok.is(tok::annot_pragma_fp));
3497 reinterpret_cast<TokFPAnnotValue *
>(Tok.getAnnotationValue());
3499 if (AnnotValue->ReassociateValue)
3500 Actions.ActOnPragmaFPValueChangingOption(
3504 if (AnnotValue->ReciprocalValue)
3505 Actions.ActOnPragmaFPValueChangingOption(
3509 if (AnnotValue->ContractValue)
3510 Actions.ActOnPragmaFPContract(Tok.getLocation(),
3511 *AnnotValue->ContractValue);
3512 if (AnnotValue->ExceptionsValue)
3513 Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
3514 *AnnotValue->ExceptionsValue);
3515 if (AnnotValue->EvalMethodValue)
3516 Actions.ActOnPragmaFPEvalMethod(Tok.getLocation(),
3517 *AnnotValue->EvalMethodValue);
3518 ConsumeAnnotationToken();
3523 Token Option,
bool ValueInParens,
3526 int OpenParens = ValueInParens ? 1 : 0;
3528 while (
Tok.isNot(tok::eod)) {
3529 if (
Tok.is(tok::l_paren))
3531 else if (
Tok.is(tok::r_paren)) {
3533 if (OpenParens == 0 && ValueInParens)
3541 if (ValueInParens) {
3543 if (
Tok.isNot(tok::r_paren)) {
3544 PP.
Diag(
Tok.getLocation(), diag::err_expected) << tok::r_paren;
3612void PragmaLoopHintHandler::HandlePragma(
Preprocessor &PP,
3627 while (
Tok.
is(tok::identifier)) {
3631 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->
getName())
3632 .Case(
"vectorize",
true)
3633 .Case(
"interleave",
true)
3634 .Case(
"unroll",
true)
3635 .Case(
"distribute",
true)
3636 .Case(
"vectorize_predicate",
true)
3637 .Case(
"vectorize_width",
true)
3638 .Case(
"interleave_count",
true)
3639 .Case(
"unroll_count",
true)
3640 .Case(
"pipeline",
true)
3641 .Case(
"pipeline_initiation_interval",
true)
3645 <<
false << OptionInfo;
3665 LoopHintTok.
setKind(tok::annot_pragma_loop_hint);
3669 TokenList.push_back(LoopHintTok);
3678 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3679 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3681 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3706void PragmaUnrollHintHandler::HandlePragma(
Preprocessor &PP,
3714 if (
Tok.
is(tok::eod)) {
3716 Info->PragmaName = PragmaName;
3717 Info->Option.startToken();
3727 bool ValueInParens =
Tok.
is(tok::l_paren);
3739 PP.
Diag(Info->Toks[0].getLocation(),
3740 diag::warn_pragma_unroll_cuda_value_in_parens);
3750 auto TokenArray = std::make_unique<Token[]>(1);
3751 TokenArray[0].startToken();
3752 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3753 TokenArray[0].setLocation(Introducer.
Loc);
3754 TokenArray[0].setAnnotationEndLoc(PragmaName.
getLocation());
3755 TokenArray[0].setAnnotationValue(
static_cast<void *
>(Info));
3756 PP.EnterTokenStream(std::move(TokenArray), 1,
3760bool Parser::HandlePragmaMSFunction(StringRef PragmaName,
3762 Token FirstTok = Tok;
3764 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3768 bool SuggestIntrinH = !PP.isMacroDefined(
"__INTRIN_H");
3770 llvm::SmallVector<StringRef> NoBuiltins;
3771 while (Tok.is(tok::identifier)) {
3772 IdentifierInfo *II = Tok.getIdentifierInfo();
3774 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3775 << II << SuggestIntrinH;
3777 NoBuiltins.emplace_back(II->
getName());
3780 if (Tok.isNot(tok::comma))
3785 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3787 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3791 Actions.ActOnPragmaMSFunction(FirstTok.
getLocation(), NoBuiltins);
3795bool Parser::HandlePragmaMSOptimize(StringRef PragmaName,
3797 Token FirstTok = Tok;
3798 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3802 if (Tok.isNot(tok::string_literal)) {
3803 PP.Diag(PragmaLocation, diag::warn_pragma_expected_string) << PragmaName;
3811 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
3816 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_comma,
3820 if (Tok.is(tok::eof) || Tok.is(tok::r_paren)) {
3821 PP.Diag(PragmaLocation, diag::warn_pragma_missing_argument)
3822 << PragmaName <<
true <<
"'on' or 'off'";
3825 IdentifierInfo *II = Tok.getIdentifierInfo();
3826 if (!II || (!II->
isStr(
"on") && !II->
isStr(
"off"))) {
3827 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3828 << PP.getSpelling(Tok) << PragmaName <<
true
3832 bool IsOn = II->
isStr(
"on");
3835 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3840 if (!OptimizationList->
getString().empty()) {
3841 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3842 << OptimizationList->
getString() << PragmaName <<
true
3847 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3851 Actions.ActOnPragmaMSOptimize(FirstTok.
getLocation(), IsOn);
3868bool Parser::HandlePragmaMSIntrinsic(StringRef PragmaName,
3870 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3874 bool SuggestIntrinH = !PP.isMacroDefined(
"__INTRIN_H");
3876 while (Tok.is(tok::identifier)) {
3877 IdentifierInfo *II = Tok.getIdentifierInfo();
3879 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3880 << II << SuggestIntrinH;
3882 DeclarationNameInfo NameInfo(II, Tok.getLocation());
3885 Actions.LookupName(
Previous, Actions.getCurScope(),
3888 Actions.LazilyCreateBuiltin(II, II->
getBuiltinID(), Actions.getCurScope(),
3889 true, Tok.getLocation());
3891 if (Tok.isNot(tok::comma))
3895 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3899 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3905void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3911 if (!Info || (!Info->
isStr(
"begin") && !Info->
isStr(
"end"))) {
3913 diag::warn_pragma_force_cuda_host_device_bad_arg);
3917 if (Info->
isStr(
"begin"))
3918 Actions.CUDA().PushForceHostDevice();
3919 else if (!Actions.CUDA().PopForceHostDevice())
3921 diag::err_pragma_cannot_end_force_cuda_host_device);
3924 if (!
Tok.
is(tok::eod))
3926 diag::warn_pragma_force_cuda_host_device_bad_arg);
3956void PragmaAttributeHandler::HandlePragma(
Preprocessor &PP,
3958 Token &FirstToken) {
3962 PragmaAttributeInfo(AttributesForPragmaAttribute);
3965 if (
Tok.
is(tok::identifier)) {
3967 if (!II->
isStr(
"push") && !II->
isStr(
"pop")) {
3968 Info->Namespace = II;
3971 if (!
Tok.
is(tok::period)) {
3980 if (!
Tok.
isOneOf(tok::identifier, tok::l_paren)) {
3982 diag::err_pragma_attribute_expected_push_pop_paren);
3987 if (
Tok.
is(tok::l_paren)) {
3988 if (Info->Namespace) {
3990 diag::err_pragma_attribute_namespace_on_attribute);
3992 diag::note_pragma_attribute_namespace_on_attribute);
3995 Info->Action = PragmaAttributeInfo::Attribute;
3998 if (II->
isStr(
"push"))
3999 Info->Action = PragmaAttributeInfo::Push;
4000 else if (II->
isStr(
"pop"))
4001 Info->Action = PragmaAttributeInfo::Pop;
4012 if ((Info->Action == PragmaAttributeInfo::Push &&
Tok.
isNot(tok::eod)) ||
4013 Info->Action == PragmaAttributeInfo::Attribute) {
4024 if (
Tok.
is(tok::l_paren))
4026 else if (
Tok.
is(tok::r_paren)) {
4028 if (OpenParens == 0)
4032 AttributeTokens.push_back(
Tok);
4036 if (AttributeTokens.empty()) {
4052 AttributeTokens.push_back(EOFTok);
4054 markAsReinjectedForRelexing(AttributeTokens);
4061 <<
"clang attribute";
4064 auto TokenArray = std::make_unique<Token[]>(1);
4065 TokenArray[0].startToken();
4066 TokenArray[0].setKind(tok::annot_pragma_attribute);
4067 TokenArray[0].setLocation(FirstToken.
getLocation());
4068 TokenArray[0].setAnnotationEndLoc(FirstToken.
getLocation());
4069 TokenArray[0].setAnnotationValue(
static_cast<void *
>(Info));
4070 PP.EnterTokenStream(std::move(TokenArray), 1,
4075void PragmaMaxTokensHereHandler::HandlePragma(
Preprocessor &PP,
4079 if (
Tok.
is(tok::eod)) {
4081 <<
"clang max_tokens_here" <<
true <<
"integer";
4087 if (
Tok.
isNot(tok::numeric_constant) ||
4090 <<
"clang max_tokens_here";
4096 <<
"clang max_tokens_here";
4101 PP.
Diag(Loc, diag::warn_max_tokens)
4107void PragmaMaxTokensTotalHandler::HandlePragma(
Preprocessor &PP,
4111 if (
Tok.
is(tok::eod)) {
4113 <<
"clang max_tokens_total" <<
true <<
"integer";
4119 if (
Tok.
isNot(tok::numeric_constant) ||
4122 <<
"clang max_tokens_total";
4128 <<
"clang max_tokens_total";
4140 Token &FirstToken) {
4145 if (!II || !II->
isStr(
"intrinsic")) {
4153 if (!II || !(II->
isStr(
"vector") || II->
isStr(
"sifive_vector") ||
4154 II->
isStr(
"andes_vector"))) {
4157 <<
"'vector', 'sifive_vector' or 'andes_vector'";
4164 <<
"clang riscv intrinsic";
4168 if (II->
isStr(
"vector"))
4169 Actions.RISCV().DeclareRVVBuiltins =
true;
4170 else if (II->
isStr(
"sifive_vector"))
4171 Actions.RISCV().DeclareSiFiveVectorBuiltins =
true;
4172 else if (II->
isStr(
"andes_vector"))
4173 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