clang: lib/Parse/ParsePragma.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/StringSwitch.h"
29#include
30using namespace clang;
31
32namespace {
33
35 explicit PragmaAlignHandler() : PragmaHandler("align") {}
37 Token &FirstToken) override;
38};
39
40struct PragmaGCCVisibilityHandler : public PragmaHandler {
41 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
43 Token &FirstToken) override;
44};
45
46struct PragmaOptionsHandler : public PragmaHandler {
47 explicit PragmaOptionsHandler() : PragmaHandler("options") {}
49 Token &FirstToken) override;
50};
51
53 explicit PragmaPackHandler() : PragmaHandler("pack") {}
55 Token &FirstToken) override;
56};
57
58struct PragmaClangSectionHandler : public PragmaHandler {
59 explicit PragmaClangSectionHandler(Sema &S)
62 Token &FirstToken) override;
63
64private:
65 Sema &Actions;
66};
67
68struct PragmaMSStructHandler : public PragmaHandler {
69 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
71 Token &FirstToken) override;
72};
73
74struct PragmaUnusedHandler : public PragmaHandler {
75 PragmaUnusedHandler() : PragmaHandler("unused") {}
77 Token &FirstToken) override;
78};
79
81 explicit PragmaWeakHandler() : PragmaHandler("weak") {}
83 Token &FirstToken) override;
84};
85
86struct PragmaRedefineExtnameHandler : public PragmaHandler {
87 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
89 Token &FirstToken) override;
90};
91
92struct PragmaOpenCLExtensionHandler : public PragmaHandler {
93 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
95 Token &FirstToken) override;
96};
97
98
99struct PragmaFPContractHandler : public PragmaHandler {
100 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
102 Token &FirstToken) override;
103};
104
105
106
107
108struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
109 PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
110
112 Token &Tok) override {
113 Token PragmaName = Tok;
117 return;
118 }
121 return;
122
124 1);
125 Toks[0].startToken();
126 Toks[0].setKind(tok::annot_pragma_fenv_access);
128 Toks[0].setAnnotationEndLoc(Tok.getLocation());
129 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
131 PP.EnterTokenStream(Toks, true,
132 false);
133 }
134};
135
136
137struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
138 PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
139
141 Token &Tok) override {
144 return;
145
148
149 Toks[0].startToken();
150 Toks[0].setKind(tok::annot_pragma_cx_limited_range);
152 Toks[0].setAnnotationEndLoc(Tok.getLocation());
153 Toks[0].setAnnotationValue(
154 reinterpret_cast<void *>(static_cast<uintptr_t>(OOS)));
155 PP.EnterTokenStream(Toks, true,
156 false);
157 }
158};
159
160
161struct PragmaSTDC_FENV_ROUNDHandler : public PragmaHandler {
162 PragmaSTDC_FENV_ROUNDHandler() : PragmaHandler("FENV_ROUND") {}
163
165 Token &Tok) override;
166};
167
168
169struct PragmaSTDC_UnknownHandler : public PragmaHandler {
170 PragmaSTDC_UnknownHandler() = default;
171
173 Token &UnknownTok) override {
174
175 PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
176 }
177};
178
182 Token &FirstToken) override;
183};
184
185
186
187
188template <diag::kind IgnoredDiag>
189struct PragmaNoSupportHandler : public PragmaHandler {
190 PragmaNoSupportHandler(StringRef Name) : PragmaHandler(Name) {}
192 Token &FirstToken) override;
193};
194
195struct PragmaNoOpenMPHandler
196 : public PragmaNoSupportHandlerdiag::warn\_pragma\_omp\_ignored {
197 PragmaNoOpenMPHandler() : PragmaNoSupportHandler("omp") {}
198};
199
200struct PragmaNoOpenACCHandler
201 : public PragmaNoSupportHandlerdiag::warn\_pragma\_acc\_ignored {
202 PragmaNoOpenACCHandler() : PragmaNoSupportHandler("acc") {}
203};
204
205
206
207
210struct PragmaSupportHandler : public PragmaHandler {
211 PragmaSupportHandler(StringRef Name) : PragmaHandler(Name) {}
213 Token &FirstToken) override;
214};
215
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") {}
221};
222
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") {}
228};
229
230
231struct PragmaCommentHandler : public PragmaHandler {
232 PragmaCommentHandler(Sema &Actions)
235 Token &FirstToken) override;
236
237private:
238 Sema &Actions;
239};
240
241struct PragmaDetectMismatchHandler : public PragmaHandler {
242 PragmaDetectMismatchHandler(Sema &Actions)
243 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
245 Token &FirstToken) override;
246
247private:
248 Sema &Actions;
249};
250
251struct PragmaFloatControlHandler : public PragmaHandler {
252 PragmaFloatControlHandler(Sema &Actions)
255 Token &FirstToken) override;
256};
257
258struct PragmaMSPointersToMembers : public PragmaHandler {
259 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
261 Token &FirstToken) override;
262};
263
265 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
267 Token &FirstToken) override;
268};
269
271 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
273 Token &FirstToken) override;
274};
275
276
277struct PragmaOptimizeHandler : public PragmaHandler {
278 PragmaOptimizeHandler(Sema &S)
281 Token &FirstToken) override;
282
283private:
284 Sema &Actions;
285};
286
287struct PragmaLoopHintHandler : public PragmaHandler {
288 PragmaLoopHintHandler() : PragmaHandler("loop") {}
290 Token &FirstToken) override;
291};
292
293struct PragmaUnrollHintHandler : public PragmaHandler {
294 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
296 Token &FirstToken) override;
297};
298
300 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
301};
302
303struct PragmaMSIntrinsicHandler : public PragmaHandler {
304 PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
306 Token &FirstToken) override;
307};
308
309
310struct PragmaMSFenvAccessHandler : public PragmaHandler {
311 PragmaMSFenvAccessHandler() : PragmaHandler("fenv_access") {}
313 Token &FirstToken) override {
316 PP.Diag(FirstToken.getLocation(), diag::warn_pragma_fp_ignored)
317 << PragmaName;
318 return;
319 }
320
322 PP.Lex(Tok);
323 if (Tok.isNot(tok::l_paren)) {
324 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
325 << PragmaName;
326 return;
327 }
328 PP.Lex(Tok);
329 if (Tok.isNot(tok::identifier)) {
330 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
331 return;
332 }
335 if (II->isStr("on")) {
337 PP.Lex(Tok);
338 } else if (II->isStr("off")) {
340 PP.Lex(Tok);
341 } else {
342 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_fenv_access);
343 return;
344 }
345 if (Tok.isNot(tok::r_paren)) {
346 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
347 << PragmaName;
348 return;
349 }
350 PP.Lex(Tok);
351
352 if (Tok.isNot(tok::eod)) {
353 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
354 << PragmaName;
355 return;
356 }
357
360 Toks[0].startToken();
361 Toks[0].setKind(tok::annot_pragma_fenv_access_ms);
362 Toks[0].setLocation(FirstToken.getLocation());
363 Toks[0].setAnnotationEndLoc(Tok.getLocation());
364 Toks[0].setAnnotationValue(
365 reinterpret_cast<void*>(static_cast<uintptr_t>(OOS)));
366 PP.EnterTokenStream(Toks, true,
367 false);
368 }
369};
370
371struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
372 PragmaForceCUDAHostDeviceHandler(Sema &Actions)
373 : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
375 Token &FirstToken) override;
376
377private:
378 Sema &Actions;
379};
380
381
382struct PragmaAttributeHandler : public PragmaHandler {
384 : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
386 Token &FirstToken) override;
387
388
390};
391
392struct PragmaMaxTokensHereHandler : public PragmaHandler {
393 PragmaMaxTokensHereHandler() : PragmaHandler("max_tokens_here") {}
395 Token &FirstToken) override;
396};
397
398struct PragmaMaxTokensTotalHandler : public PragmaHandler {
399 PragmaMaxTokensTotalHandler() : PragmaHandler("max_tokens_total") {}
401 Token &FirstToken) override;
402};
403
404struct PragmaRISCVHandler : public PragmaHandler {
405 PragmaRISCVHandler(Sema &Actions)
408 Token &FirstToken) override;
409
410private:
411 Sema &Actions;
412};
413
415 for (auto &T : Toks)
417}
418}
419
420void Parser::initializePragmaHandlers() {
421 AlignHandler = std::make_unique();
423
424 GCCVisibilityHandler = std::make_unique();
426
427 OptionsHandler = std::make_unique();
429
430 PackHandler = std::make_unique();
432
433 MSStructHandler = std::make_unique();
435
436 UnusedHandler = std::make_unique();
438
439 WeakHandler = std::make_unique();
441
442 RedefineExtnameHandler = std::make_unique();
444
445 FPContractHandler = std::make_unique();
447
448 STDCFenvAccessHandler = std::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
450
451 STDCFenvRoundHandler = std::make_unique<PragmaSTDC_FENV_ROUNDHandler>();
453
454 STDCCXLIMITHandler = std::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
456
457 STDCUnknownHandler = std::make_unique<PragmaSTDC_UnknownHandler>();
459
460 PCSectionHandler = std::make_unique(Actions);
462
464 OpenCLExtensionHandler = std::make_unique();
466
468 }
470 OpenMPHandler = std::make_unique();
471 else
472 OpenMPHandler = std::make_unique();
474
476 OpenACCHandler = std::make_unique();
477 else
478 OpenACCHandler = std::make_unique();
480
482 getTargetInfo().getTriple().isOSBinFormatELF()) {
483 MSCommentHandler = std::make_unique(Actions);
485 }
486
487 FloatControlHandler = std::make_unique(Actions);
490 MSDetectMismatchHandler =
491 std::make_unique(Actions);
493 MSPointersToMembers = std::make_unique();
495 MSVtorDisp = std::make_unique();
497 MSInitSeg = std::make_unique("init_seg");
499 MSDataSeg = std::make_unique("data_seg");
501 MSBSSSeg = std::make_unique("bss_seg");
503 MSConstSeg = std::make_unique("const_seg");
505 MSCodeSeg = std::make_unique("code_seg");
507 MSSection = std::make_unique("section");
509 MSStrictGuardStackCheck =
510 std::make_unique("strict_gs_check");
512 MSFunction = std::make_unique("function");
514 MSAllocText = std::make_unique("alloc_text");
516 MSOptimize = std::make_unique("optimize");
518 MSRuntimeChecks = std::make_unique();
520 MSIntrinsic = std::make_unique();
522 MSFenvAccess = std::make_unique();
524 }
525
527 CUDAForceHostDeviceHandler =
528 std::make_unique(Actions);
529 PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
530 }
531
532 OptimizeHandler = std::make_unique(Actions);
534
535 LoopHintHandler = std::make_unique();
537
538 UnrollHintHandler = std::make_unique("unroll");
541
542 NoUnrollHintHandler = std::make_unique("nounroll");
545
546 UnrollAndJamHintHandler =
547 std::make_unique("unroll_and_jam");
549
550 NoUnrollAndJamHintHandler =
551 std::make_unique("nounroll_and_jam");
553
554 FPHandler = std::make_unique();
556
557 AttributePragmaHandler =
558 std::make_unique(AttrFactory);
560
561 MaxTokensHerePragmaHandler = std::make_unique();
562 PP.AddPragmaHandler("clang", MaxTokensHerePragmaHandler.get());
563
564 MaxTokensTotalPragmaHandler = std::make_unique();
565 PP.AddPragmaHandler("clang", MaxTokensTotalPragmaHandler.get());
566
568 RISCVPragmaHandler = std::make_unique(Actions);
570 }
571}
572
573void Parser::resetPragmaHandlers() {
574
576 AlignHandler.reset();
578 GCCVisibilityHandler.reset();
580 OptionsHandler.reset();
582 PackHandler.reset();
584 MSStructHandler.reset();
586 UnusedHandler.reset();
588 WeakHandler.reset();
590 RedefineExtnameHandler.reset();
591
594 OpenCLExtensionHandler.reset();
596 }
598 OpenMPHandler.reset();
599
601 OpenACCHandler.reset();
602
604 getTargetInfo().getTriple().isOSBinFormatELF()) {
606 MSCommentHandler.reset();
607 }
608
610 PCSectionHandler.reset();
611
613 FloatControlHandler.reset();
616 MSDetectMismatchHandler.reset();
618 MSPointersToMembers.reset();
620 MSVtorDisp.reset();
622 MSInitSeg.reset();
624 MSDataSeg.reset();
626 MSBSSSeg.reset();
628 MSConstSeg.reset();
630 MSCodeSeg.reset();
632 MSSection.reset();
634 MSStrictGuardStackCheck.reset();
636 MSFunction.reset();
638 MSAllocText.reset();
640 MSRuntimeChecks.reset();
642 MSIntrinsic.reset();
644 MSOptimize.reset();
646 MSFenvAccess.reset();
647 }
648
651 CUDAForceHostDeviceHandler.reset();
652 }
653
655 FPContractHandler.reset();
656
658 STDCFenvAccessHandler.reset();
659
661 STDCFenvRoundHandler.reset();
662
664 STDCCXLIMITHandler.reset();
665
667 STDCUnknownHandler.reset();
668
670 OptimizeHandler.reset();
671
673 LoopHintHandler.reset();
674
677 UnrollHintHandler.reset();
678
681 NoUnrollHintHandler.reset();
682
684 UnrollAndJamHintHandler.reset();
685
687 NoUnrollAndJamHintHandler.reset();
688
690 FPHandler.reset();
691
693 AttributePragmaHandler.reset();
694
696 MaxTokensHerePragmaHandler.reset();
697
699 MaxTokensTotalPragmaHandler.reset();
700
703 RISCVPragmaHandler.reset();
704 }
705}
706
707
708
709
710
711
712void Parser::HandlePragmaUnused() {
713 assert(Tok.is(tok::annot_pragma_unused));
717}
718
719void Parser::HandlePragmaVisibility() {
720 assert(Tok.is(tok::annot_pragma_vis));
725}
726
727void Parser::HandlePragmaPack() {
728 assert(Tok.is(tok::annot_pragma_pack));
733 if (Info->Alignment.is(tok::numeric_constant)) {
736 ConsumeAnnotationToken();
737 return;
738 }
739 }
741 Alignment.get());
742
743
744 ConsumeAnnotationToken();
745}
746
747void Parser::HandlePragmaMSStruct() {
748 assert(Tok.is(tok::annot_pragma_msstruct));
752 ConsumeAnnotationToken();
753}
754
755void Parser::HandlePragmaAlign() {
756 assert(Tok.is(tok::annot_pragma_align));
761
762
763 ConsumeAnnotationToken();
764}
765
766void Parser::HandlePragmaDump() {
767 assert(Tok.is(tok::annot_pragma_dump));
768 ConsumeAnnotationToken();
769 if (Tok.is(tok::eod)) {
770 PP.Diag(Tok, diag::warn_pragma_debug_missing_argument) << "dump";
771 } else if (NextToken().is(tok::eod)) {
772 if (Tok.isNot(tok::identifier)) {
773 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_argument);
775 ExpectAndConsume(tok::eod);
776 return;
777 }
781 } else {
787
788 } else if (E.get()->getDependence() != ExprDependence::None) {
789 PP.Diag(StartLoc, diag::warn_pragma_debug_dependent_argument)
792 } else {
794 }
796 }
797 ExpectAndConsume(tok::eod);
798}
799
800void Parser::HandlePragmaWeak() {
801 assert(Tok.is(tok::annot_pragma_weak));
806}
807
808void Parser::HandlePragmaWeakAlias() {
809 assert(Tok.is(tok::annot_pragma_weakalias));
818 WeakNameLoc, AliasNameLoc);
819
820}
821
822void Parser::HandlePragmaRedefineExtname() {
823 assert(Tok.is(tok::annot_pragma_redefine_extname));
832 RedefNameLoc, AliasNameLoc);
833}
834
835void Parser::HandlePragmaFPContract() {
836 assert(Tok.is(tok::annot_pragma_fp_contract));
840
842 switch (OOS) {
845 break;
848 break;
850
851
852
853
854
855 FPC = getLangOpts().getDefaultFPContractMode();
856 break;
857 }
858
861}
862
863void Parser::HandlePragmaFloatControl() {
864 assert(Tok.is(tok::annot_pragma_float_control));
865
866
867
868
869
870
877}
878
879void Parser::HandlePragmaFEnvAccess() {
880 assert(Tok.is(tok::annot_pragma_fenv_access) ||
881 Tok.is(tok::annot_pragma_fenv_access_ms));
885
886 bool IsEnabled;
887 switch (OOS) {
889 IsEnabled = true;
890 break;
892 IsEnabled = false;
893 break;
894 case tok::OOS_DEFAULT:
895 IsEnabled = false;
896 break;
897 }
898
901}
902
903void Parser::HandlePragmaFEnvRound() {
904 assert(Tok.is(tok::annot_pragma_fenv_round));
905 auto RM = static_castllvm::RoundingMode\(
907
910}
911
912void Parser::HandlePragmaCXLimitedRange() {
913 assert(Tok.is(tok::annot_pragma_cx_limited_range));
916
918 switch (OOS) {
921 break;
924 break;
926
927
928
930 break;
931 }
932
935}
936
937StmtResult Parser::HandlePragmaCaptured()
938{
939 assert(Tok.is(tok::annot_pragma_captured));
940 ConsumeAnnotationToken();
941
942 if (Tok.isNot(tok::l_brace)) {
943 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
945 }
946
948
952 1);
953
954 StmtResult R = ParseCompoundStatement();
955 CapturedRegionScope.Exit();
956
960 }
961
963}
964
965namespace {
966 enum OpenCLExtState : char {
967 Disable, Enable, Begin, End
968 };
969 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
970}
971
972void Parser::HandlePragmaOpenCLExtension() {
973 assert(Tok.is(tok::annot_pragma_opencl_extension));
975 auto State = Data->second;
976 auto Ident = Data->first;
978 ConsumeAnnotationToken();
979
981 auto Name = Ident->getName();
982
983
984
985 if (Name == "all") {
986 if (State == Disable)
987 Opt.disableAll();
988 else
989 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
990 } else if (State == Begin) {
991 if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
992 Opt.support(Name);
993
994
995 Opt.acceptsPragma(Name);
996 }
997 } else if (State == End) {
998
999
1000 } else if (!Opt.isKnown(Name) || !Opt.isWithPragma(Name))
1001 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
1002 else if (Opt.isSupportedExtension(Name, getLangOpts()))
1003 Opt.enable(Name, State == Enable);
1004 else if (Opt.isSupportedCoreOrOptionalCore(Name, getLangOpts()))
1005 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
1006 else
1007 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
1008}
1009
1010void Parser::HandlePragmaMSPointersToMembers() {
1011 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
1015 SourceLocation PragmaLoc = ConsumeAnnotationToken();
1017}
1018
1019void Parser::HandlePragmaMSVtorDisp() {
1020 assert(Tok.is(tok::annot_pragma_ms_vtordisp));
1025 SourceLocation PragmaLoc = ConsumeAnnotationToken();
1027}
1028
1029void Parser::HandlePragmaMSPragma() {
1030 assert(Tok.is(tok::annot_pragma_ms_pragma));
1031
1032 auto TheTokens =
1033 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
1034 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true,
1035 true);
1036 SourceLocation PragmaLocation = ConsumeAnnotationToken();
1039 PP.Lex(Tok);
1040
1041
1042
1045 llvm::StringSwitch(PragmaName)
1046 .Case("data_seg", &Parser::HandlePragmaMSSegment)
1047 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
1048 .Case("const_seg", &Parser::HandlePragmaMSSegment)
1049 .Case("code_seg", &Parser::HandlePragmaMSSegment)
1050 .Case("section", &Parser::HandlePragmaMSSection)
1051 .Case("init_seg", &Parser::HandlePragmaMSInitSeg)
1052 .Case("strict_gs_check", &Parser::HandlePragmaMSStrictGuardStackCheck)
1053 .Case("function", &Parser::HandlePragmaMSFunction)
1054 .Case("alloc_text", &Parser::HandlePragmaMSAllocText)
1055 .Case("optimize", &Parser::HandlePragmaMSOptimize);
1056
1057 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
1058
1059
1060 while (Tok.isNot(tok::eof))
1061 PP.Lex(Tok);
1062 PP.Lex(Tok);
1063 }
1064}
1065
1066bool Parser::HandlePragmaMSSection(StringRef PragmaName,
1068 if (Tok.isNot(tok::l_paren)) {
1069 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
1070 return false;
1071 }
1072 PP.Lex(Tok);
1073
1074 if (Tok.isNot(tok::string_literal)) {
1075 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
1076 << PragmaName;
1077 return false;
1078 }
1081 return false;
1082 StringLiteral *SegmentName = cast(StringResult.get());
1084 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1085 << PragmaName;
1086 return false;
1087 }
1089 bool SectionFlagsAreDefault = true;
1090 while (Tok.is(tok::comma)) {
1091 PP.Lex(Tok);
1092
1093
1094
1095 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
1096 PP.Lex(Tok);
1097 continue;
1098 }
1099
1101 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
1102 << PragmaName;
1103 return false;
1104 }
1106 llvm::StringSwitchASTContext::PragmaSectionFlag(
1119 ? diag::warn_pragma_invalid_specific_action
1120 : diag::warn_pragma_unsupported_action)
1122 return false;
1123 }
1124 SectionFlags |= Flag;
1125 SectionFlagsAreDefault = false;
1126 PP.Lex(Tok);
1127 }
1128
1129
1130 if (SectionFlagsAreDefault)
1132 if (Tok.isNot(tok::r_paren)) {
1133 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
1134 return false;
1135 }
1136 PP.Lex(Tok);
1137 if (Tok.isNot(tok::eof)) {
1138 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
1139 << PragmaName;
1140 return false;
1141 }
1142 PP.Lex(Tok);
1144 return true;
1145}
1146
1147bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
1149 if (Tok.isNot(tok::l_paren)) {
1150 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
1151 return false;
1152 }
1153 PP.Lex(Tok);
1155 StringRef SlotLabel;
1158 if (PushPop == "push")
1160 else if (PushPop == "pop")
1162 else {
1163 PP.Diag(PragmaLocation,
1164 diag::warn_pragma_expected_section_push_pop_or_name)
1165 << PragmaName;
1166 return false;
1167 }
1169 PP.Lex(Tok);
1170 if (Tok.is(tok::comma)) {
1171 PP.Lex(Tok);
1172
1175 PP.Lex(Tok);
1176 if (Tok.is(tok::comma))
1177 PP.Lex(Tok);
1178 else if (Tok.isNot(tok::r_paren)) {
1179 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
1180 << PragmaName;
1181 return false;
1182 }
1183 }
1184 } else if (Tok.isNot(tok::r_paren)) {
1185 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
1186 return false;
1187 }
1188 }
1189 }
1190
1192 if (Tok.isNot(tok::r_paren)) {
1193 if (Tok.isNot(tok::string_literal)) {
1194 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
1195 diag::warn_pragma_expected_section_name :
1196 diag::warn_pragma_expected_section_label_or_name :
1197 diag::warn_pragma_expected_section_push_pop_or_name;
1198 PP.Diag(PragmaLocation, DiagID) << PragmaName;
1199 return false;
1200 }
1203 return false;
1204 SegmentName = cast(StringResult.get());
1206 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1207 << PragmaName;
1208 return false;
1209 }
1210
1213 }
1214 if (Tok.isNot(tok::r_paren)) {
1215 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
1216 return false;
1217 }
1218 PP.Lex(Tok);
1219 if (Tok.isNot(tok::eof)) {
1220 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
1221 << PragmaName;
1222 return false;
1223 }
1224 PP.Lex(Tok);
1226 SegmentName, PragmaName);
1227 return true;
1228}
1229
1230
1231bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
1233 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
1234 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
1235 return false;
1236 }
1237
1238 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1239 PragmaName))
1240 return false;
1241
1242
1246 StringRef Section = llvm::StringSwitch(II->getName())
1247 .Case("compiler", "\".CRT$XCC\"")
1248 .Case("lib", "\".CRT$XCL\"")
1249 .Case("user", "\".CRT$XCU\"")
1250 .Default("");
1251
1252 if (!Section.empty()) {
1253
1256 Toks[0].setKind(tok::string_literal);
1259 Toks[0].setLength(Section.size());
1260 SegmentName =
1262 PP.Lex(Tok);
1263 }
1264 } else if (Tok.is(tok::string_literal)) {
1267 return false;
1268 SegmentName = cast(StringResult.get());
1270 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1271 << PragmaName;
1272 return false;
1273 }
1274
1275 }
1276
1277 if (!SegmentName) {
1278 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
1279 return false;
1280 }
1281
1282 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1283 PragmaName) ||
1284 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1285 PragmaName))
1286 return false;
1287
1289 return true;
1290}
1291
1292
1293
1294
1295bool Parser::HandlePragmaMSStrictGuardStackCheck(
1296 StringRef PragmaName, SourceLocation PragmaLocation) {
1297 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1298 PragmaName))
1299 return false;
1300
1302 if (Tok.is(tok::identifier)) {
1304 if (PushPop == "push") {
1305 PP.Lex(Tok);
1307 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_punc,
1308 PragmaName))
1309 return false;
1310 } else if (PushPop == "pop") {
1311 PP.Lex(Tok);
1313 }
1314 }
1315
1316 bool Value = false;
1319 if (II && II->isStr("off")) {
1320 PP.Lex(Tok);
1322 } else if (II && II->isStr("on")) {
1323 PP.Lex(Tok);
1325 } else {
1326 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
1327 << PragmaName;
1328 return false;
1329 }
1330 }
1331
1332
1333 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1334 PragmaName))
1335 return false;
1336
1337 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1338 PragmaName))
1339 return false;
1340
1342 return true;
1343}
1344
1345bool Parser::HandlePragmaMSAllocText(StringRef PragmaName,
1347 Token FirstTok = Tok;
1348 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
1349 PragmaName))
1350 return false;
1351
1352 StringRef Section;
1353 if (Tok.is(tok::string_literal)) {
1356 return false;
1357 StringLiteral *SegmentName = cast(StringResult.get());
1359 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
1360 << PragmaName;
1361 return false;
1362 }
1363 Section = SegmentName->getString();
1364 } else if (Tok.is(tok::identifier)) {
1366 PP.Lex(Tok);
1367 } else {
1368 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
1369 << PragmaName;
1370 return false;
1371 }
1372
1373 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_comma,
1374 PragmaName))
1375 return false;
1376
1378 while (true) {
1379 if (Tok.isNot(tok::identifier)) {
1380 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1381 << PragmaName;
1382 return false;
1383 }
1384
1386 Functions.emplace_back(II, Tok.getLocation());
1387
1388 PP.Lex(Tok);
1389 if (Tok.isNot(tok::comma))
1390 break;
1391 PP.Lex(Tok);
1392 }
1393
1394 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
1395 PragmaName) ||
1396 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
1397 PragmaName))
1398 return false;
1399
1401 return true;
1402}
1403
1406 std::string ClangLoopStr("clang loop ");
1409 return std::string(llvm::StringSwitch(Str)
1410 .Case("loop", ClangLoopStr)
1411 .Case("unroll_and_jam", Str)
1412 .Case("unroll", Str)
1414}
1415
1416bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
1417 assert(Tok.is(tok::annot_pragma_loop_hint));
1420
1424
1425
1426
1429 : nullptr;
1432
1434
1435
1436
1437 auto IsLoopHint = llvm::StringSwitch(PragmaNameInfo->getName())
1438 .Cases("unroll", "nounroll", "unroll_and_jam",
1439 "nounroll_and_jam", true)
1440 .Default(false);
1441
1442 if (Toks.empty() && IsLoopHint) {
1443 ConsumeAnnotationToken();
1445 return true;
1446 }
1447
1448
1449
1450 assert(!Toks.empty() &&
1451 "PragmaLoopHintInfo::Toks must contain at least one token.");
1452
1453
1454 bool OptionUnroll = false;
1455 bool OptionUnrollAndJam = false;
1456 bool OptionDistribute = false;
1457 bool OptionPipelineDisabled = false;
1458 bool StateOption = false;
1459 if (OptionInfo) {
1460 OptionUnroll = OptionInfo->isStr("unroll");
1461 OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
1462 OptionDistribute = OptionInfo->isStr("distribute");
1463 OptionPipelineDisabled = OptionInfo->isStr("pipeline");
1464 StateOption = llvm::StringSwitch(OptionInfo->getName())
1465 .Case("vectorize", true)
1466 .Case("interleave", true)
1467 .Case("vectorize_predicate", true)
1468 .Default(false) ||
1469 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1470 OptionPipelineDisabled;
1471 }
1472
1473 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1474 !OptionDistribute && !OptionPipelineDisabled;
1475
1476 if (Toks[0].is(tok::eof)) {
1477 ConsumeAnnotationToken();
1478 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1479 << StateOption
1480 << (OptionUnroll || OptionUnrollAndJam)
1481 << AssumeSafetyArg;
1482 return false;
1483 }
1484
1485
1486 if (StateOption) {
1487 ConsumeAnnotationToken();
1489 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1490
1491 bool Valid = StateInfo &&
1492 llvm::StringSwitch(StateInfo->getName())
1493 .Case("disable", true)
1494 .Case("enable", !OptionPipelineDisabled)
1495 .Case("full", OptionUnroll || OptionUnrollAndJam)
1496 .Case("assume_safety", AssumeSafetyArg)
1497 .Default(false);
1498 if (!Valid) {
1499 if (OptionPipelineDisabled) {
1500 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1501 } else {
1502 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1503 << (OptionUnroll || OptionUnrollAndJam)
1504 << AssumeSafetyArg;
1505 }
1506 return false;
1507 }
1508 if (Toks.size() > 2)
1509 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1512 } else if (OptionInfo && OptionInfo->getName() == "vectorize_width") {
1513 PP.EnterTokenStream(Toks, false,
1514 false);
1515 ConsumeAnnotationToken();
1516
1518 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1519 StringRef IsScalableStr = StateInfo ? StateInfo->getName() : "";
1520
1521
1522 if (IsScalableStr == "scalable" || IsScalableStr == "fixed") {
1523 PP.Lex(Tok);
1524
1525 if (Toks.size() > 2) {
1526 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1528 while (Tok.isNot(tok::eof))
1530 }
1531
1534
1535 ConsumeToken();
1536 } else {
1537
1539
1540 if (R.isInvalid() && !Tok.is(tok::comma))
1541 Diag(Toks[0].getLocation(),
1542 diag::note_pragma_loop_invalid_vectorize_option);
1543
1544 bool Arg2Error = false;
1545 if (Tok.is(tok::comma)) {
1546 PP.Lex(Tok);
1547
1549 IsScalableStr = StateInfo->getName();
1550
1551 if (IsScalableStr != "scalable" && IsScalableStr != "fixed") {
1553 diag::err_pragma_loop_invalid_vectorize_option);
1554 Arg2Error = true;
1555 } else
1558
1559 PP.Lex(Tok);
1560 }
1561
1562
1563
1564 if (Tok.isNot(tok::eof)) {
1565 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1567 while (Tok.isNot(tok::eof))
1569 }
1570
1571 ConsumeToken();
1572
1573 if (Arg2Error || R.isInvalid() ||
1575 false))
1576 return false;
1577
1578
1580 }
1581 } else {
1582
1583 PP.EnterTokenStream(Toks, false,
1584 false);
1585 ConsumeAnnotationToken();
1587
1588
1589
1590 if (Tok.isNot(tok::eof)) {
1591 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1593 while (Tok.isNot(tok::eof))
1595 }
1596
1597 ConsumeToken();
1598
1601 true))
1602 return false;
1603
1604
1606 }
1607
1609 Info->Toks.back().getLocation());
1610 return true;
1611}
1612
1613namespace {
1614struct PragmaAttributeInfo {
1615 enum ActionType { Push, Pop, Attribute };
1617 ActionType Action;
1620
1621 PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1622};
1623
1624#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1625
1626}
1627
1629 if (Tok.is(tok::identifier))
1632 if (!S)
1633 return "";
1634 return S;
1635}
1636
1638 using namespace attr;
1639 switch (Rule) {
1640#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1641 case Value: \
1642 return IsAbstract;
1643#include "clang/Basic/AttrSubMatchRulesList.inc"
1644 }
1645 llvm_unreachable("Invalid attribute subject match rule");
1646 return false;
1647}
1648
1653 PRef.Diag(SubRuleLoc,
1654 diag::err_pragma_attribute_expected_subject_sub_identifier)
1655 << PrimaryRuleName;
1656 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1657 Diagnostic << 1 << SubRules;
1658 else
1659 Diagnostic << 0;
1660}
1661
1665
1667 PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1668 << SubRuleName << PrimaryRuleName;
1669 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1670 Diagnostic << 1 << SubRules;
1671 else
1672 Diagnostic << 0;
1673}
1674
1675bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1678 bool IsAny = false;
1682 IsAny = true;
1683 if (AnyParens.expectAndConsume())
1684 return true;
1685 }
1686
1687 do {
1688
1690 if (Name.empty()) {
1691 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1692 return true;
1693 }
1694 std::pair<std::optionalattr::SubjectMatchRule,
1695 std::optionalattr::SubjectMatchRule (*)(StringRef, bool)>
1696 Rule = isAttributeSubjectMatchRule(Name);
1697 if (.first) {
1698 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1699 return true;
1700 }
1703
1706 if (Parens.expectAndConsume())
1707 return true;
1708 } else if (Parens.consumeOpen()) {
1709 if (!SubjectMatchRules
1710 .insert(
1711 std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1712 .second)
1713 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1714 << Name
1716 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1717 LastMatchRuleEndLoc = RuleLoc;
1718 continue;
1719 }
1720
1721
1723 if (SubRuleName.empty()) {
1726 return true;
1727 }
1729 if (SubRuleName == "unless") {
1732 if (Parens.expectAndConsume())
1733 return true;
1735 if (SubRuleName.empty()) {
1737 SubRuleLoc);
1738 return true;
1739 }
1740 auto SubRuleOrNone = Rule.second(SubRuleName, true);
1741 if (!SubRuleOrNone) {
1742 std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1744 SubRuleUnlessName, SubRuleLoc);
1745 return true;
1746 }
1747 SubRule = *SubRuleOrNone;
1749 if (Parens.consumeClose())
1750 return true;
1751 } else {
1752 auto SubRuleOrNone = Rule.second(SubRuleName, false);
1753 if (!SubRuleOrNone) {
1756 return true;
1757 }
1758 SubRule = *SubRuleOrNone;
1760 }
1762 LastMatchRuleEndLoc = RuleEndLoc;
1763 if (Parens.consumeClose())
1764 return true;
1765 if (!SubjectMatchRules
1766 .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1767 .second) {
1768 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1771 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1772 continue;
1773 }
1775
1776 if (IsAny)
1777 if (AnyParens.consumeClose())
1778 return true;
1779
1780 return false;
1781}
1782
1783namespace {
1784
1785
1786enum class MissingAttributeSubjectRulesRecoveryPoint {
1788 ApplyTo,
1789 Equals,
1790 Any,
1792};
1793
1794MissingAttributeSubjectRulesRecoveryPoint
1795getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1797 if (II->isStr("apply_to"))
1798 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1799 if (II->isStr("any"))
1800 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1801 }
1802 if (Tok.is(tok::equal))
1803 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1804 return MissingAttributeSubjectRulesRecoveryPoint::None;
1805}
1806
1807
1808
1809
1810DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1812 MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
1817 std::string FixIt;
1818 MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1819 getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1820 if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1822 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1823 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1824 FixIt += "apply_to";
1825 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1826 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1829 if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1830
1831
1833
1834 for (const ParsedAttr &Attribute : Attrs) {
1836 Attribute.getMatchRules(PRef.getLangOpts(), MatchRules);
1838 for (const auto &Rule : MatchRules) {
1839
1840
1841 if (.second)
1842 continue;
1843 IsSupported[Rule.first] = true;
1844 }
1845 IsMatchRuleAvailable &= IsSupported;
1846 }
1847 if (IsMatchRuleAvailable.count() == 0) {
1848
1849
1851 }
1852 FixIt += "any(";
1853 bool NeedsComma = false;
1855 if (!IsMatchRuleAvailable[I])
1856 continue;
1857 if (NeedsComma)
1859 else
1860 NeedsComma = true;
1863 }
1865
1868 }
1869 if (FixItRange.getBegin() == FixItRange.getEnd())
1871 else
1875}
1876
1877}
1878
1879void Parser::HandlePragmaAttribute() {
1880 assert(Tok.is(tok::annot_pragma_attribute) &&
1881 "Expected #pragma attribute annotation token");
1883 auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1884 if (Info->Action == PragmaAttributeInfo::Pop) {
1885 ConsumeAnnotationToken();
1887 return;
1888 }
1889
1890 assert((Info->Action == PragmaAttributeInfo::Push ||
1891 Info->Action == PragmaAttributeInfo::Attribute) &&
1892 "Unexpected #pragma attribute command");
1893
1894 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1895 ConsumeAnnotationToken();
1897 return;
1898 }
1899
1900 PP.EnterTokenStream(Info->Tokens, false,
1901 false);
1902 ConsumeAnnotationToken();
1903
1906
1907 auto SkipToEnd = [this]() {
1910 };
1911
1912 if ((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
1914
1915 ParseCXX11AttributeSpecifier(Attrs);
1916 } else if (Tok.is(tok::kw___attribute)) {
1918 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1919 "attribute"))
1920 return SkipToEnd();
1921 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1922 return SkipToEnd();
1923
1924
1925
1926 if (Tok.is(tok::code_completion)) {
1927 cutOffParsing();
1928
1931 return SkipToEnd();
1932 }
1933
1934
1935 do {
1936 if (Tok.isNot(tok::identifier)) {
1937 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1938 SkipToEnd();
1939 return;
1940 }
1943
1944 if (Tok.isNot(tok::l_paren))
1945 Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1946 ParsedAttr::Form::GNU());
1947 else
1948 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, nullptr,
1949 nullptr,
1951 ParsedAttr::Form::GNU(),
1952 nullptr);
1954
1955 if (ExpectAndConsume(tok::r_paren))
1956 return SkipToEnd();
1957 if (ExpectAndConsume(tok::r_paren))
1958 return SkipToEnd();
1959 } else if (Tok.is(tok::kw___declspec)) {
1960 ParseMicrosoftDeclSpecs(Attrs);
1961 } else {
1962 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1964
1965
1971 if (Tok.is(tok::l_paren)) {
1974 if (Tok.isNot(tok::r_paren))
1975 return SkipToEnd();
1976 }
1977 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1980 }
1981 }
1982 SkipToEnd();
1983 return;
1984 }
1985
1986 if (Attrs.empty() || Attrs.begin()->isInvalid()) {
1987 SkipToEnd();
1988 return;
1989 }
1990
1991 for (const ParsedAttr &Attribute : Attrs) {
1992 if (!Attribute.isSupportedByPragmaAttribute()) {
1993 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1994 << Attribute;
1995 SkipToEnd();
1996 return;
1997 }
1998 }
1999
2000
2002 createExpectedAttributeSubjectRulesTokenDiagnostic(
2003 diag::err_expected, Attrs,
2004 MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
2005 << tok::comma;
2006 SkipToEnd();
2007 return;
2008 }
2009
2010 if (Tok.isNot(tok::identifier)) {
2011 createExpectedAttributeSubjectRulesTokenDiagnostic(
2012 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
2013 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
2014 SkipToEnd();
2015 return;
2016 }
2018 if (!II->isStr("apply_to")) {
2019 createExpectedAttributeSubjectRulesTokenDiagnostic(
2020 diag::err_pragma_attribute_invalid_subject_set_specifier, Attrs,
2021 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
2022 SkipToEnd();
2023 return;
2024 }
2026
2028 createExpectedAttributeSubjectRulesTokenDiagnostic(
2029 diag::err_expected, Attrs,
2030 MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
2031 << tok::equal;
2032 SkipToEnd();
2033 return;
2034 }
2035
2038 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
2039 LastMatchRuleEndLoc)) {
2040 SkipToEnd();
2041 return;
2042 }
2043
2044
2045
2046 if (Tok.isNot(tok::eof)) {
2047 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
2048 SkipToEnd();
2049 return;
2050 }
2051
2052
2054
2055
2056 if (Info->Action == PragmaAttributeInfo::Push)
2058
2059 for (ParsedAttr &Attribute : Attrs) {
2061 SubjectMatchRules);
2062 }
2063}
2064
2065
2066
2067
2068void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
2070 Token &VisTok) {
2072
2075
2077
2079 if (PushPop && PushPop->isStr("pop")) {
2080 VisType = nullptr;
2081 } else if (PushPop && PushPop->isStr("push")) {
2083 if (Tok.isNot(tok::l_paren)) {
2084 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
2085 << "visibility";
2086 return;
2087 }
2090 if (!VisType) {
2091 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2092 << "visibility";
2093 return;
2094 }
2096 if (Tok.isNot(tok::r_paren)) {
2097 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
2098 << "visibility";
2099 return;
2100 }
2101 } else {
2102 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2103 << "visibility";
2104 return;
2105 }
2108 if (Tok.isNot(tok::eod)) {
2109 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2110 << "visibility";
2111 return;
2112 }
2113
2114 auto Toks = std::make_unique<Token[]>(1);
2115 Toks[0].startToken();
2116 Toks[0].setKind(tok::annot_pragma_vis);
2117 Toks[0].setLocation(VisLoc);
2118 Toks[0].setAnnotationEndLoc(EndLoc);
2119 Toks[0].setAnnotationValue(
2120 const_cast<void *>(static_cast<const void *>(VisType)));
2121 PP.EnterTokenStream(std::move(Toks), 1, true,
2122 false);
2123}
2124
2125
2126
2127
2128
2129
2130void PragmaPackHandler::HandlePragma(Preprocessor &PP,
2132 Token &PackTok) {
2134
2136 PP.Lex(Tok);
2137 if (Tok.isNot(tok::l_paren)) {
2138 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
2139 return;
2140 }
2141
2143 StringRef SlotLabel;
2144 Token Alignment;
2146 PP.Lex(Tok);
2147 if (Tok.is(tok::numeric_constant)) {
2148 Alignment = Tok;
2149
2150 PP.Lex(Tok);
2151
2152
2153
2154
2158 } else if (Tok.is(tok::identifier)) {
2159
2160 auto MapPack = [&](const char *Literal) {
2162 Alignment = Tok;
2163 Alignment.setKind(tok::numeric_constant);
2166 };
2167
2169 if (II->isStr("show")) {
2171 PP.Lex(Tok);
2172 } else if (II->isStr("packed") && PP.getLangOpts().ZOSExt) {
2173
2174 MapPack("1");
2175 PP.Lex(Tok);
2177
2178 MapPack("4");
2179 PP.Lex(Tok);
2180 } else if (II->isStr("twobyte") && PP.getLangOpts().ZOSExt) {
2181
2182 MapPack("2");
2183 PP.Lex(Tok);
2185
2187 PP.Lex(Tok);
2188 } else {
2189 if (II->isStr("push")) {
2191 } else if (II->isStr("pop")) {
2193 } else {
2194 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
2195 return;
2196 }
2197 PP.Lex(Tok);
2198
2199 if (Tok.is(tok::comma)) {
2200 PP.Lex(Tok);
2201
2202 if (Tok.is(tok::numeric_constant)) {
2204 Alignment = Tok;
2205
2206 PP.Lex(Tok);
2207 } else if (Tok.is(tok::identifier)) {
2209 PP.Lex(Tok);
2210
2211 if (Tok.is(tok::comma)) {
2212 PP.Lex(Tok);
2213
2214 if (Tok.isNot(tok::numeric_constant)) {
2215 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
2216 return;
2217 }
2218
2220 Alignment = Tok;
2221
2222 PP.Lex(Tok);
2223 }
2224 } else {
2225 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
2226 return;
2227 }
2228 }
2229 }
2230 } else if (PP.getLangOpts().ApplePragmaPack ||
2232
2233
2234
2235
2237 }
2238
2239 if (Tok.isNot(tok::r_paren)) {
2240 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
2241 return;
2242 }
2243
2245 PP.Lex(Tok);
2246 if (Tok.isNot(tok::eod)) {
2247 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
2248 return;
2249 }
2250
2253 Info->Action = Action;
2256
2258 1);
2259 Toks[0].startToken();
2260 Toks[0].setKind(tok::annot_pragma_pack);
2261 Toks[0].setLocation(PackLoc);
2262 Toks[0].setAnnotationEndLoc(RParenLoc);
2263 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2264 PP.EnterTokenStream(Toks, true,
2265 false);
2266}
2267
2268
2269
2270void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
2272 Token &MSStructTok) {
2274
2276 PP.Lex(Tok);
2277 if (Tok.isNot(tok::identifier)) {
2278 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
2279 return;
2280 }
2283 if (II->isStr("on")) {
2285 PP.Lex(Tok);
2286 }
2287 else if (II->isStr("off") || II->isStr("reset"))
2288 PP.Lex(Tok);
2289 else {
2290 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
2291 return;
2292 }
2293
2294 if (Tok.isNot(tok::eod)) {
2295 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2296 << "ms_struct";
2297 return;
2298 }
2299
2301 1);
2302 Toks[0].startToken();
2303 Toks[0].setKind(tok::annot_pragma_msstruct);
2304 Toks[0].setLocation(MSStructTok.getLocation());
2305 Toks[0].setAnnotationEndLoc(EndLoc);
2306 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2308 PP.EnterTokenStream(Toks, true,
2309 false);
2310}
2311
2312
2313void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
2315 Token &FirstToken) {
2316
2319
2320 PP.Lex(Tok);
2321 while (Tok.isNot(tok::eod)) {
2322 if (Tok.isNot(tok::identifier)) {
2323 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
2324 return;
2325 }
2326
2328 if (SecType->isStr("bss"))
2330 else if (SecType->isStr("data"))
2332 else if (SecType->isStr("rodata"))
2334 else if (SecType->isStr("relro"))
2336 else if (SecType->isStr("text"))
2338 else {
2339 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
2340 return;
2341 }
2342
2344 PP.Lex(Tok);
2345 if (Tok.isNot(tok::equal)) {
2346 PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
2347 return;
2348 }
2349
2350 std::string SecName;
2351 if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
2352 return;
2353
2354 Actions.ActOnPragmaClangSection(
2355 PragmaLocation,
2358 SecKind, SecName);
2359 }
2360}
2361
2362
2363
2364
2366 bool IsOptions) {
2368
2369 if (IsOptions) {
2370 PP.Lex(Tok);
2371 if (Tok.isNot(tok::identifier) ||
2373 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
2374 return;
2375 }
2376 }
2377
2378 PP.Lex(Tok);
2380 if (Tok.isNot(tok::l_paren)) {
2381 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "align";
2382 return;
2383 }
2384 } else if (Tok.isNot(tok::equal)) {
2385 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
2386 << IsOptions;
2387 return;
2388 }
2389
2390 PP.Lex(Tok);
2391 if (Tok.isNot(tok::identifier)) {
2392 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2393 << (IsOptions ? "options" : "align");
2394 return;
2395 }
2396
2399 if (II->isStr("native"))
2401 else if (II->isStr("natural"))
2403 else if (II->isStr("packed"))
2405 else if (II->isStr("power"))
2407 else if (II->isStr("mac68k"))
2409 else if (II->isStr("reset"))
2411 else {
2412 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
2413 << IsOptions;
2414 return;
2415 }
2416
2418 PP.Lex(Tok);
2419 if (Tok.isNot(tok::r_paren)) {
2420 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "align";
2421 return;
2422 }
2423 }
2424
2426 PP.Lex(Tok);
2427 if (Tok.isNot(tok::eod)) {
2428 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2429 << (IsOptions ? "options" : "align");
2430 return;
2431 }
2432
2434 1);
2435 Toks[0].startToken();
2436 Toks[0].setKind(tok::annot_pragma_align);
2437 Toks[0].setLocation(FirstTok.getLocation());
2438 Toks[0].setAnnotationEndLoc(EndLoc);
2439 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2441 PP.EnterTokenStream(Toks, true,
2442 false);
2443}
2444
2445void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
2447 Token &AlignTok) {
2449}
2450
2451void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
2453 Token &OptionsTok) {
2455}
2456
2457
2458void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
2460 Token &UnusedTok) {
2461
2463
2464
2466 PP.Lex(Tok);
2467 if (Tok.isNot(tok::l_paren)) {
2468 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
2469 return;
2470 }
2471
2472
2475 bool LexID = true;
2476
2477 while (true) {
2478 PP.Lex(Tok);
2479
2480 if (LexID) {
2481 if (Tok.is(tok::identifier)) {
2482 Identifiers.push_back(Tok);
2483 LexID = false;
2484 continue;
2485 }
2486
2487
2488 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
2489 return;
2490 }
2491
2492
2493 if (Tok.is(tok::comma)) {
2494 LexID = true;
2495 continue;
2496 }
2497
2498 if (Tok.is(tok::r_paren)) {
2500 break;
2501 }
2502
2503
2504 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
2505 return;
2506 }
2507
2508 PP.Lex(Tok);
2509 if (Tok.isNot(tok::eod)) {
2510 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2511 "unused";
2512 return;
2513 }
2514
2515
2516 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'");
2517 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments");
2518
2519
2520
2521
2522
2523
2526 2 * Identifiers.size());
2527 for (unsigned i=0; i != Identifiers.size(); i++) {
2528 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
2530 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
2532 idTok = Identifiers[i];
2533 }
2534 PP.EnterTokenStream(Toks, true,
2535 false);
2536}
2537
2538
2539
2540void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
2542 Token &WeakTok) {
2544
2546 PP.Lex(Tok);
2547 if (Tok.isNot(tok::identifier)) {
2548 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
2549 return;
2550 }
2551
2552 Token WeakName = Tok;
2553 bool HasAlias = false;
2554 Token AliasName;
2555
2556 PP.Lex(Tok);
2557 if (Tok.is(tok::equal)) {
2558 HasAlias = true;
2559 PP.Lex(Tok);
2560 if (Tok.isNot(tok::identifier)) {
2561 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2562 << "weak";
2563 return;
2564 }
2565 AliasName = Tok;
2566 PP.Lex(Tok);
2567 }
2568
2569 if (Tok.isNot(tok::eod)) {
2570 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
2571 return;
2572 }
2573
2574 if (HasAlias) {
2577 Token &pragmaUnusedTok = Toks[0];
2579 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
2582 Toks[1] = WeakName;
2583 Toks[2] = AliasName;
2584 PP.EnterTokenStream(Toks, true,
2585 false);
2586 } else {
2589 Token &pragmaUnusedTok = Toks[0];
2591 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
2594 Toks[1] = WeakName;
2595 PP.EnterTokenStream(Toks, true,
2596 false);
2597 }
2598}
2599
2600
2601void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
2603 Token &RedefToken) {
2605
2607 PP.Lex(Tok);
2608 if (Tok.isNot(tok::identifier)) {
2609 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2610 "redefine_extname";
2611 return;
2612 }
2613
2614 Token RedefName = Tok;
2615 PP.Lex(Tok);
2616
2617 if (Tok.isNot(tok::identifier)) {
2618 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2619 << "redefine_extname";
2620 return;
2621 }
2622
2623 Token AliasName = Tok;
2624 PP.Lex(Tok);
2625
2626 if (Tok.isNot(tok::eod)) {
2627 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2628 "redefine_extname";
2629 return;
2630 }
2631
2633 3);
2634 Token &pragmaRedefTok = Toks[0];
2636 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2639 Toks[1] = RedefName;
2640 Toks[2] = AliasName;
2641 PP.EnterTokenStream(Toks, true,
2642 false);
2643}
2644
2645void PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2650 return;
2651
2653 1);
2654 Toks[0].startToken();
2655 Toks[0].setKind(tok::annot_pragma_fp_contract);
2657 Toks[0].setAnnotationEndLoc(Tok.getLocation());
2658 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2660 PP.EnterTokenStream(Toks, true,
2661 false);
2662}
2663
2664void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2668 if (Tok.isNot(tok::identifier)) {
2669 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2670 "OPENCL";
2671 return;
2672 }
2675
2676 PP.Lex(Tok);
2677 if (Tok.isNot(tok::colon)) {
2678 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2679 return;
2680 }
2681
2682 PP.Lex(Tok);
2683 if (Tok.isNot(tok::identifier)) {
2684 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2685 return;
2686 }
2688
2689 OpenCLExtState State;
2690 if (Pred->isStr("enable")) {
2691 State = Enable;
2692 } else if (Pred->isStr("disable")) {
2693 State = Disable;
2694 } else if (Pred->isStr("begin"))
2696 else if (Pred->isStr("end"))
2697 State = End;
2698 else {
2699 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2700 << Ext->isStr("all");
2701 return;
2702 }
2704
2705 PP.Lex(Tok);
2706 if (Tok.isNot(tok::eod)) {
2707 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2708 "OPENCL EXTENSION";
2709 return;
2710 }
2711
2713 Info->first = Ext;
2714 Info->second = State;
2716 1);
2717 Toks[0].startToken();
2718 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2719 Toks[0].setLocation(NameLoc);
2720 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2721 Toks[0].setAnnotationEndLoc(StateLoc);
2722 PP.EnterTokenStream(Toks, true,
2723 false);
2724
2727 StateLoc, State);
2728}
2729
2730
2731
2732template <diag::kind IgnoredDiag>
2733void PragmaNoSupportHandler::HandlePragma(
2736 PP.Diag(FirstTok, IgnoredDiag);
2739 }
2741}
2742
2743
2744
2747void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
2754
2755 while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
2756 Pragma.push_back(Tok);
2757 PP.Lex(Tok);
2758 if (Tok.is(StartTok)) {
2759 PP.Diag(Tok, UnexpectedDiag) << 0;
2760 unsigned InnerPragmaCnt = 1;
2761 while (InnerPragmaCnt != 0) {
2762 PP.Lex(Tok);
2763 if (Tok.is(StartTok))
2764 ++InnerPragmaCnt;
2765 else if (Tok.is(EndTok))
2766 --InnerPragmaCnt;
2767 }
2768 PP.Lex(Tok);
2769 }
2770 }
2775 Pragma.push_back(Tok);
2776
2777 auto Toks = std::make_unique<Token[]>(Pragma.size());
2778 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2779 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2780 false, false);
2781}
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2795 PP.Lex(Tok);
2796 if (Tok.isNot(tok::l_paren)) {
2797 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2798 << "pointers_to_members";
2799 return;
2800 }
2801 PP.Lex(Tok);
2803 if (!Arg) {
2804 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2805 << "pointers_to_members";
2806 return;
2807 }
2808 PP.Lex(Tok);
2809
2811 if (Arg->isStr("best_case")) {
2813 } else {
2814 if (Arg->isStr("full_generality")) {
2815 if (Tok.is(tok::comma)) {
2816 PP.Lex(Tok);
2817
2819 if (!Arg) {
2821 diag::err_pragma_pointers_to_members_unknown_kind)
2822 << Tok.getKind() << 0;
2823 return;
2824 }
2825 PP.Lex(Tok);
2826 } else if (Tok.is(tok::r_paren)) {
2827
2828
2829 Arg = nullptr;
2831 } else {
2833 << "full_generality";
2834 return;
2835 }
2836 }
2837
2838 if (Arg) {
2839 if (Arg->isStr("single_inheritance")) {
2840 RepresentationMethod =
2842 } else if (Arg->isStr("multiple_inheritance")) {
2843 RepresentationMethod =
2845 } else if (Arg->isStr("virtual_inheritance")) {
2846 RepresentationMethod =
2848 } else {
2850 diag::err_pragma_pointers_to_members_unknown_kind)
2851 << Arg << 1;
2852 return;
2853 }
2854 }
2855 }
2856
2857 if (Tok.isNot(tok::r_paren)) {
2858 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2859 << (Arg ? Arg->getName() : "full_generality");
2860 return;
2861 }
2862
2864 PP.Lex(Tok);
2865 if (Tok.isNot(tok::eod)) {
2866 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2867 << "pointers_to_members";
2868 return;
2869 }
2870
2873 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2874 AnnotTok.setLocation(PointersToMembersLoc);
2877 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2878 PP.EnterToken(AnnotTok, true);
2879}
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2892 PP.Lex(Tok);
2893 if (Tok.isNot(tok::l_paren)) {
2894 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2895 return;
2896 }
2897 PP.Lex(Tok);
2898
2901 if (II) {
2902 if (II->isStr("push")) {
2903
2904 PP.Lex(Tok);
2905 if (Tok.isNot(tok::comma)) {
2906 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2907 return;
2908 }
2909 PP.Lex(Tok);
2911
2912 } else if (II->isStr("pop")) {
2913
2914 PP.Lex(Tok);
2916 }
2917
2918 } else {
2919 if (Tok.is(tok::r_paren)) {
2920
2922 }
2923 }
2924
2925
2929 if (II && II->isStr("off")) {
2930 PP.Lex(Tok);
2932 } else if (II && II->isStr("on")) {
2933 PP.Lex(Tok);
2935 } else if (Tok.is(tok::numeric_constant) &&
2937 if (Value > 2) {
2938 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2939 << 0 << 2 << "vtordisp";
2940 return;
2941 }
2942 } else {
2943 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2944 << "vtordisp";
2945 return;
2946 }
2947 }
2948
2949
2950 if (Tok.isNot(tok::r_paren)) {
2951 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2952 return;
2953 }
2955 PP.Lex(Tok);
2956 if (Tok.isNot(tok::eod)) {
2957 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2958 << "vtordisp";
2959 return;
2960 }
2961
2962
2965 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2969 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2970 PP.EnterToken(AnnotTok, false);
2971}
2972
2973
2974
2975void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2977 Token EoF, AnnotTok;
2981 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2985
2986 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2987 TokenVector.push_back(Tok);
2989 }
2990
2991 TokenVector.push_back(EoF);
2992
2993
2994 markAsReinjectedForRelexing(TokenVector);
2995 auto TokenArray = std::make_unique<Token[]>(TokenVector.size());
2996 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2998 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2999 TokenVector.size());
3001 PP.EnterToken(AnnotTok, false);
3002}
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015void PragmaFloatControlHandler::HandlePragma(Preprocessor &PP,
3020 Token PragmaName = Tok;
3022 PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
3024 return;
3025 }
3026 PP.Lex(Tok);
3027 if (Tok.isNot(tok::l_paren)) {
3028 PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren;
3029 return;
3030 }
3031
3032
3033 PP.Lex(Tok);
3034 if (Tok.isNot(tok::identifier)) {
3035 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3036 return;
3037 }
3038
3039
3042 llvm::StringSwitch(II->getName())
3048 PP.Lex(Tok);
3050 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3051 return;
3053 if (Tok.isNot(tok::r_paren)) {
3054 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3055 return;
3056 }
3057 PP.Lex(Tok);
3059 } else {
3060 if (Tok.is(tok::r_paren))
3061
3062 PP.Lex(Tok);
3063 else if (Tok.isNot(tok::comma)) {
3064 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3065 return;
3066 } else {
3067 PP.Lex(Tok);
3069 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3070 return;
3071 }
3073 if (PushOnOff == "on")
3074
3075 ;
3076 else if (PushOnOff == "off") {
3081 } else if (PushOnOff == "push") {
3083 } else {
3084 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3085 return;
3086 }
3087 PP.Lex(Tok);
3088 if (Tok.is(tok::comma)) {
3089 PP.Lex(Tok);
3091 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3092 return;
3093 }
3095 if (ExpectedPush == "push") {
3097 } else {
3098 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3099 return;
3100 }
3101 PP.Lex(Tok);
3102 }
3103 if (Tok.isNot(tok::r_paren)) {
3104 PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed);
3105 return;
3106 }
3107 PP.Lex(Tok);
3108 }
3109 }
3111 if (Tok.isNot(tok::eod)) {
3112 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3113 << "float_control";
3114 return;
3115 }
3116
3117
3118
3119
3120 auto TokenArray = std::make_unique<Token[]>(1);
3121 TokenArray[0].startToken();
3122 TokenArray[0].setKind(tok::annot_pragma_float_control);
3123 TokenArray[0].setLocation(FloatControlLoc);
3124 TokenArray[0].setAnnotationEndLoc(EndLoc);
3125
3126
3127 TokenArray[0].setAnnotationValue(reinterpret_cast<void *>(
3128 static_cast<uintptr_t>((Action << 16) | (Kind & 0xFFFF))));
3129 PP.EnterTokenStream(std::move(TokenArray), 1,
3130 false, false);
3131}
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
3147 PP.Lex(Tok);
3148 if (Tok.isNot(tok::l_paren)) {
3149 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
3150 return;
3151 }
3152
3153
3154 std::string NameString;
3156 "pragma detect_mismatch",
3157 true))
3158 return;
3159
3160
3161 std::string ValueString;
3162 if (Tok.isNot(tok::comma)) {
3163 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
3164 return;
3165 }
3166
3167 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
3168 true))
3169 return;
3170
3171 if (Tok.isNot(tok::r_paren)) {
3172 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3173 return;
3174 }
3175 PP.Lex(Tok);
3176
3177 if (Tok.isNot(tok::eod)) {
3178 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
3179 return;
3180 }
3181
3182
3185 ValueString);
3186
3187 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
3188}
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
3203 PP.Lex(Tok);
3204 if (Tok.isNot(tok::l_paren)) {
3205 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
3206 return;
3207 }
3208
3209
3210 PP.Lex(Tok);
3211 if (Tok.isNot(tok::identifier)) {
3212 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
3213 return;
3214 }
3215
3216
3219 llvm::StringSwitch(II->getName())
3227 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
3228 return;
3229 }
3230
3232 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
3234 return;
3235 }
3236
3237
3238 PP.Lex(Tok);
3239 std::string ArgumentString;
3241 "pragma comment",
3242 true))
3243 return;
3244
3245
3246
3247
3248
3249
3250
3251
3252 if (Tok.isNot(tok::r_paren)) {
3253 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
3254 return;
3255 }
3256 PP.Lex(Tok);
3257
3258 if (Tok.isNot(tok::eod)) {
3259 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
3260 return;
3261 }
3262
3263
3266
3267 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
3268}
3269
3270
3271
3272void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
3274 Token &FirstToken) {
3276 PP.Lex(Tok);
3277 if (Tok.is(tok::eod)) {
3278 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
3279 << "clang optimize" << true << "'on' or 'off'";
3280 return;
3281 }
3282 if (Tok.isNot(tok::identifier)) {
3283 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
3285 return;
3286 }
3288
3289 bool IsOn = false;
3290 if (II->isStr("on")) {
3291 IsOn = true;
3292 } else if (!II->isStr("off")) {
3293 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
3295 return;
3296 }
3297 PP.Lex(Tok);
3298
3299 if (Tok.isNot(tok::eod)) {
3300 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
3302 return;
3303 }
3304
3305 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
3306}
3307
3308namespace {
3309
3310struct TokFPAnnotValue {
3311 enum FlagValues { On, Off, Fast };
3312
3313 std::optionalLangOptions::FPModeKind ContractValue;
3314 std::optionalLangOptions::FPModeKind ReassociateValue;
3315 std::optionalLangOptions::FPModeKind ReciprocalValue;
3316 std::optionalLangOptions::FPExceptionModeKind ExceptionsValue;
3317 std::optionalLangOptions::FPEvalMethodKind EvalMethodValue;
3318};
3319}
3320
3321void PragmaFPHandler::HandlePragma(Preprocessor &PP,
3323
3324 Token PragmaName = Tok;
3326
3327 PP.Lex(Tok);
3328 if (Tok.isNot(tok::identifier)) {
3329 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
3330 << true << "";
3331 return;
3332 }
3333
3335 while (Tok.is(tok::identifier)) {
3337
3338 auto FlagKind =
3339 llvm::StringSwitch<std::optional>(OptionInfo->getName())
3345 .Default(std::nullopt);
3346 if (!FlagKind) {
3347 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
3348 << false << OptionInfo;
3349 return;
3350 }
3351 PP.Lex(Tok);
3352
3353
3354 if (Tok.isNot(tok::l_paren)) {
3355 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3356 return;
3357 }
3358 PP.Lex(Tok);
3359 bool isEvalMethodDouble =
3361
3362
3363 if (Tok.isNot(tok::identifier) && !isEvalMethodDouble) {
3364 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3366 << static_cast<int>(*FlagKind);
3367 return;
3368 }
3370
3372 AnnotValue->ContractValue =
3373 llvm::StringSwitch<std::optionalLangOptions::FPModeKind>(
3378 .Default(std::nullopt);
3379 if (!AnnotValue->ContractValue) {
3380 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3382 return;
3383 }
3386 : AnnotValue->ReciprocalValue;
3387 Value = llvm::StringSwitch<std::optionalLangOptions::FPModeKind>(
3391 .Default(std::nullopt);
3393 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3395 return;
3396 }
3398 AnnotValue->ExceptionsValue =
3399 llvm::StringSwitch<std::optionalLangOptions::FPExceptionModeKind>(
3404 .Default(std::nullopt);
3405 if (!AnnotValue->ExceptionsValue) {
3406 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3408 return;
3409 }
3411 AnnotValue->EvalMethodValue =
3412 llvm::StringSwitch<std::optionalLangOptions::FPEvalMethodKind>(
3417 .Default(std::nullopt);
3418 if (!AnnotValue->EvalMethodValue) {
3419 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
3421 return;
3422 }
3423 }
3424 PP.Lex(Tok);
3425
3426
3427 if (Tok.isNot(tok::r_paren)) {
3428 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3429 return;
3430 }
3431 PP.Lex(Tok);
3432 }
3433
3434 if (Tok.isNot(tok::eod)) {
3435 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3436 << "clang fp";
3437 return;
3438 }
3439
3442 FPTok.setKind(tok::annot_pragma_fp);
3446 TokenList.push_back(FPTok);
3447
3448 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3449 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3450
3451 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3452 false, false);
3453}
3454
3455void PragmaSTDC_FENV_ROUNDHandler::HandlePragma(Preprocessor &PP,
3458 Token PragmaName = Tok;
3461 PP.Diag(Tok.getLocation(), diag::warn_pragma_fp_ignored)
3463 return;
3464 }
3465
3466 PP.Lex(Tok);
3467 if (Tok.isNot(tok::identifier)) {
3468 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
3470 return;
3471 }
3473
3474 auto RM =
3475 llvm::StringSwitchllvm::RoundingMode(II->getName())
3476 .Case("FE_TOWARDZERO", llvm::RoundingMode::TowardZero)
3477 .Case("FE_TONEAREST", llvm::RoundingMode::NearestTiesToEven)
3478 .Case("FE_UPWARD", llvm::RoundingMode::TowardPositive)
3479 .Case("FE_DOWNWARD", llvm::RoundingMode::TowardNegative)
3480 .Case("FE_TONEARESTFROMZERO", llvm::RoundingMode::NearestTiesToAway)
3481 .Case("FE_DYNAMIC", llvm::RoundingMode::Dynamic)
3482 .Default(llvm::RoundingMode::Invalid);
3483 if (RM == llvm::RoundingMode::Invalid) {
3484 PP.Diag(Tok.getLocation(), diag::warn_stdc_unknown_rounding_mode);
3485 return;
3486 }
3487 PP.Lex(Tok);
3488
3489 if (Tok.isNot(tok::eod)) {
3490 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3491 << "STDC FENV_ROUND";
3492 return;
3493 }
3494
3495
3496 PP.Diag(Tok.getLocation(), diag::warn_stdc_fenv_round_not_supported);
3497
3499 1);
3500 Toks[0].startToken();
3501 Toks[0].setKind(tok::annot_pragma_fenv_round);
3503 Toks[0].setAnnotationEndLoc(Tok.getLocation());
3504 Toks[0].setAnnotationValue(
3505 reinterpret_cast<void *>(static_cast<uintptr_t>(RM)));
3506 PP.EnterTokenStream(Toks, true,
3507 false);
3508}
3509
3510void Parser::HandlePragmaFP() {
3511 assert(Tok.is(tok::annot_pragma_fp));
3512 auto *AnnotValue =
3514
3515 if (AnnotValue->ReassociateValue)
3519
3520 if (AnnotValue->ReciprocalValue)
3524
3525 if (AnnotValue->ContractValue)
3527 *AnnotValue->ContractValue);
3528 if (AnnotValue->ExceptionsValue)
3530 *AnnotValue->ExceptionsValue);
3531 if (AnnotValue->EvalMethodValue)
3533 *AnnotValue->EvalMethodValue);
3534 ConsumeAnnotationToken();
3535}
3536
3537
3539 Token Option, bool ValueInParens,
3542 int OpenParens = ValueInParens ? 1 : 0;
3543
3544 while (Tok.isNot(tok::eod)) {
3545 if (Tok.is(tok::l_paren))
3546 OpenParens++;
3547 else if (Tok.is(tok::r_paren)) {
3548 OpenParens--;
3549 if (OpenParens == 0 && ValueInParens)
3550 break;
3551 }
3552
3554 PP.Lex(Tok);
3555 }
3556
3557 if (ValueInParens) {
3558
3559 if (Tok.isNot(tok::r_paren)) {
3560 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3561 return true;
3562 }
3563 PP.Lex(Tok);
3564 }
3565
3568 EOFTok.setKind(tok::eof);
3570 ValueList.push_back(EOFTok);
3571
3572 markAsReinjectedForRelexing(ValueList);
3574
3576 Info.Option = Option;
3577 return false;
3578}
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
3631
3632 Token PragmaName = Tok;
3634
3635
3636 PP.Lex(Tok);
3637 if (Tok.isNot(tok::identifier)) {
3638 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
3639 << true << "";
3640 return;
3641 }
3642
3643 while (Tok.is(tok::identifier)) {
3644 Token Option = Tok;
3646
3647 bool OptionValid = llvm::StringSwitch(OptionInfo->getName())
3648 .Case("vectorize", true)
3649 .Case("interleave", true)
3650 .Case("unroll", true)
3651 .Case("distribute", true)
3652 .Case("vectorize_predicate", true)
3653 .Case("vectorize_width", true)
3654 .Case("interleave_count", true)
3655 .Case("unroll_count", true)
3656 .Case("pipeline", true)
3657 .Case("pipeline_initiation_interval", true)
3658 .Default(false);
3659 if (!OptionValid) {
3660 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
3661 << false << OptionInfo;
3662 return;
3663 }
3664 PP.Lex(Tok);
3665
3666
3667 if (Tok.isNot(tok::l_paren)) {
3668 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3669 return;
3670 }
3671 PP.Lex(Tok);
3672
3674 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, true,
3675 *Info))
3676 return;
3677
3678
3679 Token LoopHintTok;
3681 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
3685 TokenList.push_back(LoopHintTok);
3686 }
3687
3688 if (Tok.isNot(tok::eod)) {
3689 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3690 << "clang loop";
3691 return;
3692 }
3693
3694 auto TokenArray = std::make_unique<Token[]>(TokenList.size());
3695 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
3696
3697 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
3698 false, false);
3699}
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
3725
3726
3727 Token PragmaName = Tok;
3728 PP.Lex(Tok);
3730 if (Tok.is(tok::eod)) {
3731
3732 Info->PragmaName = PragmaName;
3733 Info->Option.startToken();
3736 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3738 return;
3739 } else {
3740
3741
3742
3743 bool ValueInParens = Tok.is(tok::l_paren);
3744 if (ValueInParens)
3745 PP.Lex(Tok);
3746
3749 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
3750 return;
3751
3752
3753
3754 if (PP.getLangOpts().CUDA && ValueInParens)
3755 PP.Diag(Info->Toks[0].getLocation(),
3756 diag::warn_pragma_unroll_cuda_value_in_parens);
3757
3758 if (Tok.isNot(tok::eod)) {
3759 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3760 << "unroll";
3761 return;
3762 }
3763 }
3764
3765
3766 auto TokenArray = std::make_unique<Token[]>(1);
3767 TokenArray[0].startToken();
3768 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3769 TokenArray[0].setLocation(Introducer.Loc);
3770 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
3771 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3772 PP.EnterTokenStream(std::move(TokenArray), 1,
3773 false, false);
3774}
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
3791 PP.Lex(Tok);
3792
3793 if (Tok.isNot(tok::l_paren)) {
3794 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
3795 << "intrinsic";
3796 return;
3797 }
3798 PP.Lex(Tok);
3799
3800 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3801
3802 while (Tok.is(tok::identifier)) {
3805 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3806 << II << SuggestIntrinH;
3807
3808 PP.Lex(Tok);
3809 if (Tok.isNot(tok::comma))
3810 break;
3811 PP.Lex(Tok);
3812 }
3813
3814 if (Tok.isNot(tok::r_paren)) {
3815 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
3816 << "intrinsic";
3817 return;
3818 }
3819 PP.Lex(Tok);
3820
3821 if (Tok.isNot(tok::eod))
3822 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3823 << "intrinsic";
3824}
3825
3826bool Parser::HandlePragmaMSFunction(StringRef PragmaName,
3828 Token FirstTok = Tok;
3829
3830 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3831 PragmaName))
3832 return false;
3833
3834 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3835
3837 while (Tok.is(tok::identifier)) {
3840 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3841 << II << SuggestIntrinH;
3842 else
3843 NoBuiltins.emplace_back(II->getName());
3844
3845 PP.Lex(Tok);
3846 if (Tok.isNot(tok::comma))
3847 break;
3848 PP.Lex(Tok);
3849 }
3850
3851 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3852 PragmaName) ||
3853 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3854 PragmaName))
3855 return false;
3856
3858 return true;
3859}
3860
3861
3862bool Parser::HandlePragmaMSOptimize(StringRef PragmaName,
3864 Token FirstTok = Tok;
3865 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
3866 PragmaName))
3867 return false;
3868
3869 if (Tok.isNot(tok::string_literal)) {
3870 PP.Diag(PragmaLocation, diag::warn_pragma_expected_string) << PragmaName;
3871 return false;
3872 }
3875 return false;
3876 StringLiteral *OptimizationList = cast(StringResult.get());
3878 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
3879 << PragmaName;
3880 return false;
3881 }
3882
3883 if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_comma,
3884 PragmaName))
3885 return false;
3886
3887 if (Tok.is(tok::eof) || Tok.is(tok::r_paren)) {
3888 PP.Diag(PragmaLocation, diag::warn_pragma_missing_argument)
3889 << PragmaName << true << "'on' or 'off'";
3890 return false;
3891 }
3893 if (!II || (!II->isStr("on") && !II->isStr("off"))) {
3894 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3895 << PP.getSpelling(Tok) << PragmaName << true
3896 << "'on' or 'off'";
3897 return false;
3898 }
3899 bool IsOn = II->isStr("on");
3900 PP.Lex(Tok);
3901
3902 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
3903 PragmaName))
3904 return false;
3905
3906
3907 if (!OptimizationList->getString().empty()) {
3908 PP.Diag(PragmaLocation, diag::warn_pragma_invalid_argument)
3909 << OptimizationList->getString() << PragmaName << true
3910 << "\"\"";
3911 return false;
3912 }
3913
3914 if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
3915 PragmaName))
3916 return false;
3917
3919 return true;
3920}
3921
3922void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3924 Token FirstTok = Tok;
3925
3926 PP.Lex(Tok);
3928 if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
3930 diag::warn_pragma_force_cuda_host_device_bad_arg);
3931 return;
3932 }
3933
3934 if (Info->isStr("begin"))
3935 Actions.CUDA().PushForceHostDevice();
3936 else if (!Actions.CUDA().PopForceHostDevice())
3938 diag::err_pragma_cannot_end_force_cuda_host_device);
3939
3940 PP.Lex(Tok);
3941 if (!Tok.is(tok::eod))
3943 diag::warn_pragma_force_cuda_host_device_bad_arg);
3944}
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3975 Token &FirstToken) {
3977 PP.Lex(Tok);
3979 PragmaAttributeInfo(AttributesForPragmaAttribute);
3980
3981
3982 if (Tok.is(tok::identifier)) {
3984 if (!II->isStr("push") && !II->isStr("pop")) {
3985 Info->Namespace = II;
3986 PP.Lex(Tok);
3987
3988 if (!Tok.is(tok::period)) {
3989 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
3990 << II;
3991 return;
3992 }
3993 PP.Lex(Tok);
3994 }
3995 }
3996
3997 if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
3999 diag::err_pragma_attribute_expected_push_pop_paren);
4000 return;
4001 }
4002
4003
4004 if (Tok.is(tok::l_paren)) {
4005 if (Info->Namespace) {
4007 diag::err_pragma_attribute_namespace_on_attribute);
4009 diag::note_pragma_attribute_namespace_on_attribute);
4010 return;
4011 }
4012 Info->Action = PragmaAttributeInfo::Attribute;
4013 } else {
4015 if (II->isStr("push"))
4016 Info->Action = PragmaAttributeInfo::Push;
4017 else if (II->isStr("pop"))
4018 Info->Action = PragmaAttributeInfo::Pop;
4019 else {
4020 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
4022 return;
4023 }
4024
4025 PP.Lex(Tok);
4026 }
4027
4028
4029 if ((Info->Action == PragmaAttributeInfo::Push && Tok.isNot(tok::eod)) ||
4030 Info->Action == PragmaAttributeInfo::Attribute) {
4031 if (Tok.isNot(tok::l_paren)) {
4032 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
4033 return;
4034 }
4035 PP.Lex(Tok);
4036
4037
4039 int OpenParens = 1;
4040 while (Tok.isNot(tok::eod)) {
4041 if (Tok.is(tok::l_paren))
4042 OpenParens++;
4043 else if (Tok.is(tok::r_paren)) {
4044 OpenParens--;
4045 if (OpenParens == 0)
4046 break;
4047 }
4048
4049 AttributeTokens.push_back(Tok);
4050 PP.Lex(Tok);
4051 }
4052
4053 if (AttributeTokens.empty()) {
4054 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
4055 return;
4056 }
4057 if (Tok.isNot(tok::r_paren)) {
4058 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
4059 return;
4060 }
4062 PP.Lex(Tok);
4063
4064
4067 EOFTok.setKind(tok::eof);
4069 AttributeTokens.push_back(EOFTok);
4070
4071 markAsReinjectedForRelexing(AttributeTokens);
4072 Info->Tokens =
4074 }
4075
4076 if (Tok.isNot(tok::eod))
4077 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
4078 << "clang attribute";
4079
4080
4081 auto TokenArray = std::make_unique<Token[]>(1);
4082 TokenArray[0].startToken();
4083 TokenArray[0].setKind(tok::annot_pragma_attribute);
4084 TokenArray[0].setLocation(FirstToken.getLocation());
4085 TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
4086 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
4087 PP.EnterTokenStream(std::move(TokenArray), 1,
4088 false, false);
4089}
4090
4091
4092void PragmaMaxTokensHereHandler::HandlePragma(Preprocessor &PP,
4095 PP.Lex(Tok);
4096 if (Tok.is(tok::eod)) {
4097 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
4098 << "clang max_tokens_here" << true << "integer";
4099 return;
4100 }
4101
4104 if (Tok.isNot(tok::numeric_constant) ||
4106 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
4107 << "clang max_tokens_here";
4108 return;
4109 }
4110
4111 if (Tok.isNot(tok::eod)) {
4112 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
4113 << "clang max_tokens_here";
4114 return;
4115 }
4116
4118 PP.Diag(Loc, diag::warn_max_tokens)
4120 }
4121}
4122
4123
4124void PragmaMaxTokensTotalHandler::HandlePragma(Preprocessor &PP,
4127 PP.Lex(Tok);
4128 if (Tok.is(tok::eod)) {
4129 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
4130 << "clang max_tokens_total" << true << "integer";
4131 return;
4132 }
4133
4136 if (Tok.isNot(tok::numeric_constant) ||
4138 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_integer)
4139 << "clang max_tokens_total";
4140 return;
4141 }
4142
4143 if (Tok.isNot(tok::eod)) {
4144 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
4145 << "clang max_tokens_total";
4146 return;
4147 }
4148
4150}
4151
4152
4153
4154void PragmaRISCVHandler::HandlePragma(Preprocessor &PP,
4156 Token &FirstToken) {
4158 PP.Lex(Tok);
4160
4161 if (!II || !II->isStr("intrinsic")) {
4162 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
4163 << PP.getSpelling(Tok) << "riscv" << true << "'intrinsic'";
4164 return;
4165 }
4166
4167 PP.Lex(Tok);
4169 if (!II || !(II->isStr("vector") || II->isStr("sifive_vector"))) {
4170 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
4171 << PP.getSpelling(Tok) << "riscv" << true
4172 << "'vector' or 'sifive_vector'";
4173 return;
4174 }
4175
4176 PP.Lex(Tok);
4177 if (Tok.isNot(tok::eod)) {
4178 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
4179 << "clang riscv intrinsic";
4180 return;
4181 }
4182
4183 if (II->isStr("vector"))
4184 Actions.RISCV().DeclareRVVBuiltins = true;
4185 else if (II->isStr("sifive_vector"))
4186 Actions.RISCV().DeclareSiFiveVectorBuiltins = true;
4187}
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
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
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
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...
RAII object that enters a new expression evaluation context.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
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.
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.
@ 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.
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, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
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
SourceLocation getEndOfPreviousToken()
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(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken)=0
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.
bool isMacroDefined(StringRef Id)
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.
void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Add the specified pragma handler to this preprocessor.
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
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
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.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
Sema - This implements semantic analysis and AST building for C.
void ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn)
#pragma optimize("[optimization-list]", on | off).
void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, const IdentifierInfo *Namespace)
void ActOnPragmaAttributePop(SourceLocation PragmaLoc, const IdentifierInfo *Namespace)
Called on well-formed '#pragma clang attribute pop'.
void ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode)
Called to set constant rounding mode for floating point operations.
void ActOnPragmaMSSeg(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, StringLiteral *SegmentName, llvm::StringRef PragmaName)
Called on well formed #pragma bss_seg/data_seg/const_seg/code_seg.
void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, PragmaFloatControlKind Value)
ActOnPragmaFloatControl - Call on well-formed #pragma float_control.
void ActOnPragmaMSPointersToMembers(LangOptions::PragmaMSPointersToMembersKind Kind, SourceLocation PragmaLoc)
ActOnPragmaMSPointersToMembers - called on well formed #pragma pointers_to_members(representation met...
void ActOnCapturedRegionError()
void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc)
ActOnPragmaUnused - Called on well-formed '#pragma unused'.
void ActOnPragmaMSAllocText(SourceLocation PragmaLocation, StringRef Section, const SmallVector< std::tuple< IdentifierInfo *, SourceLocation > > &Functions)
Called on well-formed #pragma alloc_text().
void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, SourceLocation PragmaLoc, attr::ParsedSubjectMatchRuleSet Rules)
void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc)
ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
void ActOnPragmaCXLimitedRange(SourceLocation Loc, LangOptions::ComplexRangeKind Range)
ActOnPragmaCXLimitedRange - Called on well formed #pragma STDC CX_LIMITED_RANGE.
void ActOnPragmaFPExceptions(SourceLocation Loc, LangOptions::FPExceptionModeKind)
Called on well formed '#pragma clang fp' that has option 'exceptions'.
void ActOnPragmaFPEvalMethod(SourceLocation Loc, LangOptions::FPEvalMethodKind Value)
void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, SourceLocation PragmaLoc, MSVtorDispMode Value)
Called on well formed #pragma vtordisp().
SemaCodeCompletion & CodeCompletion()
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc, bool AllowZero)
void ActOnPragmaWeakID(IdentifierInfo *WeakName, SourceLocation PragmaLoc, SourceLocation WeakNameLoc)
ActOnPragmaWeakID - Called on well formed #pragma weak ident.
void ActOnPragmaMSFunction(SourceLocation Loc, const llvm::SmallVectorImpl< StringRef > &NoBuiltins)
Call on well formed #pragma function.
void ActOnPragmaMSStruct(PragmaMSStructKind Kind)
ActOnPragmaMSStruct - Called on well formed #pragma ms_struct [on|off].
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, StringLiteral *SegmentName)
Called on well-formed #pragma init_seg().
StmtResult ActOnCapturedRegionEnd(Stmt *S)
void ActOnPragmaFPValueChangingOption(SourceLocation Loc, PragmaFPKind Kind, bool IsEnabled)
Called on well formed #pragma clang fp reassociate or #pragma clang fp reciprocal.
void ActOnPragmaRedefineExtname(IdentifierInfo *WeakName, IdentifierInfo *AliasName, SourceLocation PragmaLoc, SourceLocation WeakNameLoc, SourceLocation AliasNameLoc)
ActOnPragmaRedefineExtname - Called on well formed #pragma redefine_extname oldname newname.
ExprResult ActOnStringLiteral(ArrayRef< Token > StringToks, Scope *UDLScope=nullptr)
ActOnStringLiteral - The specified tokens were lexed as pasted string fragments (e....
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, StringRef SlotLabel, Expr *Alignment)
ActOnPragmaPack - Called on well formed #pragma pack(...).
OpenCLOptions & getOpenCLOptions()
void ActOnPragmaVisibility(const IdentifierInfo *VisType, SourceLocation PragmaLoc)
ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation, PragmaMsStackAction Action, bool Value)
ActOnPragmaMSStrictGuardStackCheck - Called on well formed #pragma strict_gs_check.
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC)
ActOnPragmaFPContract - Called on well formed #pragma {STDC,OPENCL} FP_CONTRACT and #pragma clang fp ...
void ActOnPragmaWeakAlias(IdentifierInfo *WeakName, IdentifierInfo *AliasName, SourceLocation PragmaLoc, SourceLocation WeakNameLoc, SourceLocation AliasNameLoc)
ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II)
Called on #pragma clang __debug dump II.
void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled)
ActOnPragmaFenvAccess - Called on well formed #pragma STDC FENV_ACCESS.
void ActOnPragmaMSSection(SourceLocation PragmaLocation, int SectionFlags, StringLiteral *SegmentName)
Called on well formed #pragma section().
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.
StringLiteral - This represents a string literal expression, e.g.
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...
SourceLocation getEndLoc() const
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)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
void setAnnotationValue(void *val)
void startToken()
Reset all flags to cleared.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
llvm::DenseMap< int, SourceRange > ParsedSubjectMatchRuleSet
SubjectMatchRule
A list of all the recognized kinds of attributes.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
uint32_t Literal
Literals are represented as positive integers.
@ 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).
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
const FunctionProtoType * T
@ None
The alignment was not explicit in code.
@ Parens
New-expression has a C++98 paren-delimited initializer.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
Loop optimization hint for loop and unroll pragmas.
IdentifierLoc * OptionLoc
IdentifierLoc * PragmaNameLoc
Describes how and where the pragma was introduced.
PragmaMsStackAction Action