clang: lib/Lex/Pragma.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
36#include "llvm/ADT/ArrayRef.h"
37#include "llvm/ADT/DenseMap.h"
38#include "llvm/ADT/SmallVector.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/Support/Compiler.h"
41#include "llvm/Support/ErrorHandling.h"
42#include "llvm/Support/Timer.h"
43#include
44#include
45#include
46#include
47#include
48#include
49#include
50#include
51
52using namespace clang;
53
54
56
57
58
59
60
62
65 Token &FirstToken) {}
66
67
68
69
70
71
72
73
74
76 bool IgnoreNull) const {
77 auto I = Handlers.find(Name);
78 if (I != Handlers.end())
79 return I->getValue().get();
80 if (IgnoreNull)
81 return nullptr;
82 I = Handlers.find(StringRef());
83 if (I != Handlers.end())
84 return I->getValue().get();
85 return nullptr;
86}
87
89 assert(!Handlers.count(Handler->getName()) &&
90 "A handler with this name is already registered in this namespace");
91 Handlers[Handler->getName()].reset(Handler);
92}
93
95 auto I = Handlers.find(Handler->getName());
96 assert(I != Handlers.end() &&
97 "Handler not registered in this namespace");
98
99 I->getValue().release();
100 Handlers.erase(I);
101}
102
105
106
108
109
112 : StringRef(),
113 false);
114 if (!Handler) {
115 PP.Diag(Tok, diag::warn_pragma_ignored);
116 return;
117 }
118
119
121}
122
123
124
125
126
127namespace {
128
129
130
131struct TokenCollector {
133 bool Collect;
136
137 void lex() {
138 if (Collect)
139 Tokens.push_back(Tok);
140 Self.Lex(Tok);
141 }
142
143 void revert() {
144 assert(Collect && "did not collect tokens");
145 assert(!Tokens.empty() && "collected unexpected number of tokens");
146
147
148 auto Toks = std::make_unique<Token[]>(Tokens.size());
149 std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
150 Toks[Tokens.size() - 1] = Tok;
151 Self.EnterTokenStream(std::move(Toks), Tokens.size(),
152 true,
153 true);
154
155
156 Tok = *Tokens.begin();
157 }
158};
159}
160
161
162
163void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {
164 if (Callbacks)
165 Callbacks->PragmaDirective(Introducer.Loc, Introducer.Kind);
166
167 if (!PragmasEnabled)
168 return;
169
170 ++NumPragma;
171
172
174 PragmaHandlers->HandlePragma(*this, Introducer, Tok);
175
176
177 if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
180}
181
182
183
184
185void Preprocessor::Handle_Pragma(Token &Tok) {
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
207
208
210
211
212 Toks.lex();
213 if (Tok.isNot(tok::l_paren)) {
214 Diag(PragmaLoc, diag::err__Pragma_malformed);
215 return;
216 }
217
218
219 Toks.lex();
221 Diag(PragmaLoc, diag::err__Pragma_malformed);
222
223 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
224 Lex(Tok);
225 while (Tok.isNot(tok::r_paren) &&
227 Tok.isNot(tok::eof))
228 Lex(Tok);
229 if (Tok.is(tok::r_paren))
230 Lex(Tok);
231 return;
232 }
233
235 Diag(Tok, diag::err_invalid_string_udl);
236
237 Lex(Tok);
238 if (Tok.is(tok::r_paren))
239 Lex(Tok);
240 return;
241 }
242
243
244 Token StrTok = Tok;
245
246
247 Toks.lex();
248 if (Tok.isNot(tok::r_paren)) {
249 Diag(PragmaLoc, diag::err__Pragma_malformed);
250 return;
251 }
252
253
254 if (InMacroArgPreExpansion) {
255 Toks.revert();
256 return;
257 }
258
262 StrVal.resize(StrTok.getLength());
265 Diag(PragmaLoc, diag::err__Pragma_malformed);
266 return;
267 }
268
269 assert(StrValRef.size() <= StrVal.size());
270
271
272 if (StrValRef.begin() != StrVal.begin())
273 StrVal.assign(StrValRef);
274
275 else if (StrValRef.size() != StrVal.size())
276 StrVal.resize(StrValRef.size());
277
278
280
281
282
287
288
289
291 StrVal.size(), *this);
292
293 EnterSourceFileWithLexer(TL, nullptr);
294
295
296 HandlePragmaDirective({PIK__Pragma, PragmaLoc});
297
298
299 return Lex(Tok);
300}
301
303 if (StrVal[0] == 'L' || StrVal[0] == 'U' ||
304 (StrVal[0] == 'u' && StrVal[1] != '8'))
305 StrVal.erase(StrVal.begin());
306 else if (StrVal[0] == 'u')
307 StrVal.erase(StrVal.begin(), StrVal.begin() + 2);
308
309 if (StrVal[0] == 'R') {
310
311
312 assert(StrVal[1] == '"' && StrVal[StrVal.size() - 1] == '"' &&
313 "Invalid raw string token!");
314
315
316 unsigned NumDChars = 0;
317 while (StrVal[2 + NumDChars] != '(') {
318 assert(NumDChars < (StrVal.size() - 5) / 2 &&
319 "Invalid raw string token!");
320 ++NumDChars;
321 }
322 assert(StrVal[StrVal.size() - 2 - NumDChars] == ')');
323
324
325
326 StrVal.erase(StrVal.begin(), StrVal.begin() + 2 + NumDChars);
327 StrVal.erase(StrVal.end() - 1 - NumDChars, StrVal.end());
328 } else {
329 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
330 "Invalid string token!");
331
332
333 unsigned ResultPos = 1;
334 for (size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
335
336 if (StrVal[i] == '\\' && i + 1 < e &&
337 (StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
338 ++i;
339 StrVal[ResultPos++] = StrVal[i];
340 }
341 StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 1);
342 }
343
344
345
346 StrVal[0] = ' ';
347
348
349 StrVal[StrVal.size() - 1] = '\n';
350}
351
352
353
354void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
355
356
357 TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
358
359
361
362
363 Toks.lex();
364 if (Tok.isNot(tok::l_paren)) {
365 Diag(PragmaLoc, diag::err__Pragma_malformed);
366 return;
367 }
368
369
371 int NumParens = 0;
372 Toks.lex();
373 while (Tok.isNot(tok::eof)) {
374 PragmaToks.push_back(Tok);
375 if (Tok.is(tok::l_paren))
376 NumParens++;
377 else if (Tok.is(tok::r_paren) && NumParens-- == 0)
378 break;
379 Toks.lex();
380 }
381
382 if (Tok.is(tok::eof)) {
383 Diag(PragmaLoc, diag::err_unterminated___pragma);
384 return;
385 }
386
387
388 if (InMacroArgPreExpansion) {
389 Toks.revert();
390 return;
391 }
392
394
395
396 PragmaToks.back().setKind(tok::eod);
397
398 Token *TokArray = new Token[PragmaToks.size()];
399 std::copy(PragmaToks.begin(), PragmaToks.end(), TokArray);
400
401
402 EnterTokenStream(TokArray, PragmaToks.size(), true, true,
403 false);
404
405
406 HandlePragmaDirective({PIK___pragma, PragmaLoc});
407
408
409 return Lex(Tok);
410}
411
412
414
415
416
417
419 Diag(OnceTok, diag::pp_pragma_once_in_main_file);
420 return;
421 }
422
423
424
426}
427
429 assert(CurPPLexer && "No current lexer?");
430
432 CurLexer->ReadToEndOfLine(&Buffer);
433 if (Callbacks)
434 Callbacks->PragmaMark(MarkTok.getLocation(), Buffer);
435}
436
437
440
441 while (true) {
442
443
444
445
446
447 if (CurPPLexer) CurPPLexer->LexingRawMode = true;
449 if (CurPPLexer) CurPPLexer->LexingRawMode = false;
450
451
452 if (Tok.is(tok::eod)) return;
453
454
455 if (Tok.isNot(tok::raw_identifier)) {
456 Diag(Tok, diag::err_pp_invalid_poison);
457 return;
458 }
459
460
461
463
464
466
467
469 Diag(Tok, diag::pp_poisoning_existing_macro);
470
471
475 }
476}
477
478
479
482 Diag(SysHeaderTok, diag::pp_pragma_sysheader_in_main_file);
483 return;
484 }
485
486
488
489
491
494 return;
495
497
498
499 if (Callbacks)
500 Callbacks->FileChanged(SysHeaderTok.getLocation(),
502
503
504
505
507 FilenameID, false, false,
509}
510
511
513 Token FilenameTok;
514 if (LexHeaderName(FilenameTok, false))
515 return;
516
517
518 if (FilenameTok.isNot(tok::header_name)) {
519 Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
520 return;
521 }
522
523
528 return;
529
530 bool isAngled =
532
533
535 return;
536
537
540 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
542 if (!SuppressIncludeNotFoundError)
543 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
544 return;
545 }
546
548
549
551
552 std::string Message;
553 Lex(DependencyTok);
554 while (DependencyTok.isNot(tok::eod)) {
555 Message += getSpelling(DependencyTok) + " ";
556 Lex(DependencyTok);
557 }
558
559
560 if (!Message.empty())
561 Message.erase(Message.end()-1);
562 Diag(FilenameTok, diag::pp_out_of_date_dependency) << Message;
563 }
564}
565
566
567
569
570 Token PragmaTok = Tok;
571
572
573 Lex(Tok);
574 if (Tok.isNot(tok::l_paren)) {
575 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
577 return nullptr;
578 }
579
580
581 Lex(Tok);
582 if (Tok.isNot(tok::string_literal)) {
583 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
585 return nullptr;
586 }
587
589 Diag(Tok, diag::err_invalid_string_udl);
590 return nullptr;
591 }
592
593
595
596
597 Lex(Tok);
598 if (Tok.isNot(tok::r_paren)) {
599 Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
601 return nullptr;
602 }
603
604 assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
605 "Invalid string token!");
606
607
610 MacroTok.setKind(tok::raw_identifier);
611 CreateString(StringRef(&StrVal[1], StrVal.size() - 2), MacroTok);
612
613
615}
616
617
618
619
620
621
622
624
626 if (!IdentInfo) return;
627
628
630
631 if (MI) {
632
634 }
635
636
637 PragmaPushMacroInfo[IdentInfo].push_back(MI);
638}
639
640
641
642
643
644
645
648
649
651 if (!IdentInfo) return;
652
653
654 llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>::iterator iter =
655 PragmaPushMacroInfo.find(IdentInfo);
656 if (iter != PragmaPushMacroInfo.end()) {
657
659 if (MI->isWarnIfUnused())
660 WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
662 }
663
664
665 MacroInfo *MacroToReInstall = iter->second.back();
666
667 if (MacroToReInstall)
668
670
671
672 iter->second.pop_back();
673 if (iter->second.empty())
674 PragmaPushMacroInfo.erase(iter);
675 } else {
676 Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
678 }
679}
680
682
683
684
685
686
687
688 Lex(Tok);
689 if (Tok.isNot(tok::l_paren)) {
690 Diag(Tok, diag::warn_pragma_include_alias_expected) << "(";
691 return;
692 }
693
694
695 Token SourceFilenameTok;
697 return;
698
699 StringRef SourceFileName;
701 if (SourceFilenameTok.is(tok::header_name)) {
702 SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
703 } else {
704 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
705 return;
706 }
707 FileNameBuffer.clear();
708
709
710 Lex(Tok);
711 if (Tok.isNot(tok::comma)) {
712 Diag(Tok, diag::warn_pragma_include_alias_expected) << ",";
713 return;
714 }
715
716 Token ReplaceFilenameTok;
718 return;
719
720 StringRef ReplaceFileName;
721 if (ReplaceFilenameTok.is(tok::header_name)) {
722 ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
723 } else {
724 Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
725 return;
726 }
727
728
729 Lex(Tok);
730 if (Tok.isNot(tok::r_paren)) {
731 Diag(Tok, diag::warn_pragma_include_alias_expected) << ")";
732 return;
733 }
734
735
736
737 StringRef OriginalSource = SourceFileName;
738
739 bool SourceIsAngled =
741 SourceFileName);
742 bool ReplaceIsAngled =
744 ReplaceFileName);
745 if (!SourceFileName.empty() && !ReplaceFileName.empty() &&
746 (SourceIsAngled != ReplaceIsAngled)) {
747 unsigned int DiagID;
748 if (SourceIsAngled)
749 DiagID = diag::warn_pragma_include_alias_mismatch_angle;
750 else
751 DiagID = diag::warn_pragma_include_alias_mismatch_quote;
752
754 << SourceFileName
755 << ReplaceFileName;
756
757 return;
758 }
759
760
762}
763
764
765
768 std::pair<IdentifierInfo *, SourceLocation> &ModuleNameComponent,
771 if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) {
773 if (Literal.hadError)
774 return true;
775 ModuleNameComponent = std::make_pair(
778 ModuleNameComponent =
780 } else {
782 return true;
783 }
784 return false;
785}
786
790 &ModuleName) {
791 while (true) {
792 std::pair<IdentifierInfo*, SourceLocation> NameComponent;
794 return true;
795 ModuleName.push_back(NameComponent);
796
798 if (Tok.isNot(tok::period))
799 return false;
800 }
801}
802
805
806 std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
808 return;
810
812 if (Tok.isNot(tok::eod)) {
813 Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
815 }
816
817 CurLexer->LexingRawMode = true;
818
819 auto TryConsumeIdentifier = [&](StringRef Ident) -> bool {
820 if (Tok.getKind() != tok::raw_identifier ||
822 return false;
823 CurLexer->Lex(Tok);
824 return true;
825 };
826
827
828 const char *Start = CurLexer->getBufferLocation();
829 const char *End = nullptr;
830 unsigned NestingLevel = 1;
831 while (true) {
832 End = CurLexer->getBufferLocation();
833 CurLexer->Lex(Tok);
834
835 if (Tok.is(tok::eof)) {
836 Diag(Loc, diag::err_pp_module_build_missing_end);
837 break;
838 }
839
841
842 continue;
843 }
844
845
846
847 CurLexer->ParsingPreprocessorDirective = true;
848 CurLexer->Lex(Tok);
849 if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") &&
850 TryConsumeIdentifier("module")) {
851 if (TryConsumeIdentifier("build"))
852
853 ++NestingLevel;
854 else if (TryConsumeIdentifier("endbuild")) {
855
856 if (--NestingLevel == 0)
857 break;
858 }
859
860
861 assert(Tok.getKind() != tok::eof && "missing EOD before EOF");
862 }
863 }
864
865 CurLexer->LexingRawMode = false;
866
867
868 assert(CurLexer->getBuffer().begin() <= Start &&
869 Start <= CurLexer->getBuffer().end() &&
870 CurLexer->getBuffer().begin() <= End &&
871 End <= CurLexer->getBuffer().end() &&
872 "module source range not contained within same file buffer");
874 StringRef(Start, End - Start));
875}
876
878 Lex(Tok);
879 if (Tok.is(tok::l_paren)) {
880 Diag(Tok.getLocation(), diag::warn_pp_hdrstop_filename_ignored);
881
884 return;
885
886 if (Tok.isNot(tok::r_paren)) {
887 Diag(Tok, diag::err_expected) << tok::r_paren;
888 return;
889 }
890 Lex(Tok);
891 }
892 if (Tok.isNot(tok::eod))
893 Diag(Tok.getLocation(), diag::ext_pp_extra_tokens_at_eol)
894 << "pragma hdrstop";
895
898 assert(CurLexer && "no lexer for #pragma hdrstop processing");
901 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
902 CurLexer->cutOffLexing();
903 }
905 SkippingUntilPragmaHdrStop = false;
906}
907
908
909
910
914
915
916 if (!Namespace.empty()) {
917
918
919
920 if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
922 assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
923 " handler with the same name!");
924 } else {
925
926
928 PragmaHandlers->AddPragma(InsertNS);
929 }
930 }
931
932
934 "Pragma handler already exists for this identifier!");
936}
937
938
939
940
941
945
946
947 if (!Namespace.empty()) {
948 PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace);
949 assert(Existing && "Namespace containing handler does not exist!");
950
952 assert(NS && "Invalid namespace, registered as a regular pragma handler!");
953 }
954
956
957
958 if (NS != PragmaHandlers.get() && NS->IsEmpty()) {
959 PragmaHandlers->RemovePragmaHandler(NS);
960 delete NS;
961 }
962}
963
967
968 if (Tok.isNot(tok::identifier)) {
969 Diag(Tok, diag::ext_on_off_switch_syntax);
970 return true;
971 }
973 if (II->isStr("ON"))
975 else if (II->isStr("OFF"))
977 else if (II->isStr("DEFAULT"))
979 else {
980 Diag(Tok, diag::ext_on_off_switch_syntax);
981 return true;
982 }
983
984
986 if (Tok.isNot(tok::eod))
987 Diag(Tok, diag::ext_pragma_syntax_eod);
988 return false;
989}
990
991namespace {
992
993
996
998 Token &OnceTok) override {
1001 }
1002};
1003
1004
1005
1006struct PragmaMarkHandler : public PragmaHandler {
1008
1010 Token &MarkTok) override {
1012 }
1013};
1014
1015
1016struct PragmaPoisonHandler : public PragmaHandler {
1017 PragmaPoisonHandler() : PragmaHandler("poison") {}
1018
1020 Token &PoisonTok) override {
1022 }
1023};
1024
1025
1026
1027struct PragmaSystemHeaderHandler : public PragmaHandler {
1028 PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
1029
1031 Token &SHToken) override {
1034 }
1035};
1036
1037struct PragmaDependencyHandler : public PragmaHandler {
1038 PragmaDependencyHandler() : PragmaHandler("dependency") {}
1039
1041 Token &DepToken) override {
1043 }
1044};
1045
1046struct PragmaDebugHandler : public PragmaHandler {
1047 PragmaDebugHandler() : PragmaHandler("__debug") {}
1048
1050 Token &DebugToken) override {
1053 if (Tok.isNot(tok::identifier)) {
1054 PP.Diag(Tok, diag::warn_pragma_debug_missing_command);
1055 return;
1056 }
1058
1059 if (II->isStr("assert")) {
1061 llvm_unreachable("This is an assertion!");
1062 } else if (II->isStr("crash")) {
1063 llvm::Timer T("crash", "pragma crash");
1064 llvm::TimeRegion R(&T);
1066 LLVM_BUILTIN_TRAP;
1067 } else if (II->isStr("parser_crash")) {
1071 Crasher.setKind(tok::annot_pragma_parser_crash);
1073 PP.EnterToken(Crasher, false);
1074 }
1075 } else if (II->isStr("dump")) {
1076 Token DumpAnnot;
1078 DumpAnnot.setKind(tok::annot_pragma_dump);
1080 PP.EnterToken(DumpAnnot, false);
1081 } else if (II->isStr("diag_mapping")) {
1084 if (DiagName.is(tok::eod))
1086 else if (DiagName.is(tok::string_literal) && !DiagName.hasUDSuffix()) {
1088 StringLiteralEvalMethod::Unevaluated);
1090 return;
1092 } else {
1093 PP.Diag(DiagName, diag::warn_pragma_debug_missing_argument)
1095 }
1096 } else if (II->isStr("llvm_fatal_error")) {
1098 llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
1099 } else if (II->isStr("llvm_unreachable")) {
1101 llvm_unreachable("#pragma clang __debug llvm_unreachable");
1102 } else if (II->isStr("macro")) {
1103 Token MacroName;
1106 if (MacroII)
1108 else
1109 PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)
1111 } else if (II->isStr("module_map")) {
1113 ModuleName;
1115 return;
1117 Module *M = nullptr;
1118 for (auto IIAndLoc : ModuleName) {
1120 if (!M) {
1121 PP.Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
1122 << IIAndLoc.first;
1123 return;
1124 }
1125 }
1127 } else if (II->isStr("overflow_stack")) {
1129 DebugOverflowStack();
1130 } else if (II->isStr("captured")) {
1131 HandleCaptured(PP);
1132 } else if (II->isStr("modules")) {
1133 struct ModuleVisitor {
1135 void visit(Module *M, bool VisibleOnly) {
1137 if (!VisibleOnly || ImportLoc.isValid()) {
1139 if (ImportLoc.isValid()) {
1140 llvm::errs() << M << " visible ";
1142 }
1143 llvm::errs() << "\n";
1144 }
1146 if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)
1147 visit(Sub, VisibleOnly);
1148 }
1149 }
1150 void visitAll(bool VisibleOnly) {
1151 for (auto &NameAndMod :
1153 visit(NameAndMod.second, VisibleOnly);
1154 }
1155 } Visitor{PP};
1156
1159 auto *DumpII = Kind.getIdentifierInfo();
1160 if (!DumpII) {
1161 PP.Diag(Kind, diag::warn_pragma_debug_missing_argument)
1163 } else if (DumpII->isStr("all")) {
1164 Visitor.visitAll(false);
1165 } else if (DumpII->isStr("visible")) {
1166 Visitor.visitAll(true);
1167 } else if (DumpII->isStr("building")) {
1169 llvm::errs() << "in " << Building.M->getFullModuleName();
1170 if (Building.ImportLoc.isValid()) {
1171 llvm::errs() << " imported ";
1172 if (Building.IsPragma)
1173 llvm::errs() << "via pragma ";
1174 llvm::errs() << "at ";
1175 Building.ImportLoc.print(llvm::errs(), PP.getSourceManager());
1176 llvm::errs() << "\n";
1177 }
1178 }
1179 } else {
1180 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1181 << DumpII->getName();
1182 }
1183 } else if (II->isStr("sloc_usage")) {
1184
1185
1186 std::optional MaxNotes;
1188 PP.Lex(ArgToken);
1190 if (ArgToken.is(tok::numeric_constant) &&
1192 MaxNotes = Value;
1193 } else if (ArgToken.isNot(tok::eod)) {
1194 PP.Diag(ArgToken, diag::warn_pragma_debug_unexpected_argument);
1195 }
1196
1197 PP.Diag(Tok, diag::remark_sloc_usage);
1199 MaxNotes);
1200 } else {
1201 PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
1203 }
1204
1206 if (Callbacks)
1208 }
1209
1213
1214 if (Tok.isNot(tok::eod)) {
1215 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
1216 << "pragma clang __debug captured";
1217 return;
1218 }
1219
1223 Toks[0].startToken();
1224 Toks[0].setKind(tok::annot_pragma_captured);
1225 Toks[0].setLocation(NameLoc);
1226
1227 PP.EnterTokenStream(Toks, true,
1228 false);
1229 }
1230
1231
1232#ifdef _MSC_VER
1233 #pragma warning(disable : 4717)
1234#endif
1235 static void DebugOverflowStack(void (*P)() = nullptr) {
1236 void (*volatile Self)(void(*P)()) = DebugOverflowStack;
1237 Self(reinterpret_cast<void(*)()>(Self));
1238 }
1239#ifdef _MSC_VER
1240 #pragma warning(default : 4717)
1241#endif
1242};
1243
1244struct PragmaUnsafeBufferUsageHandler : public PragmaHandler {
1245 PragmaUnsafeBufferUsageHandler() : PragmaHandler("unsafe_buffer_usage") {}
1247 Token &FirstToken) override {
1249
1251 if (Tok.isNot(tok::identifier)) {
1252 PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1253 return;
1254 }
1255
1258
1259 if (II->isStr("begin")) {
1261 PP.Diag(Loc, diag::err_pp_double_begin_pragma_unsafe_buffer_usage);
1262 } else if (II->isStr("end")) {
1264 PP.Diag(Loc, diag::err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage);
1265 } else
1266 PP.Diag(Tok, diag::err_pp_pragma_unsafe_buffer_usage_syntax);
1267 }
1268};
1269
1270
1271struct PragmaDiagnosticHandler : public PragmaHandler {
1272private:
1274
1275public:
1276 explicit PragmaDiagnosticHandler(const char *NS)
1278
1280 Token &DiagToken) override {
1284 if (Tok.isNot(tok::identifier)) {
1285 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1286 return;
1287 }
1290
1291
1292
1294
1295 if (II->isStr("pop")) {
1297 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1298 else if (Callbacks)
1300
1301 if (Tok.isNot(tok::eod))
1302 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1303 return;
1304 } else if (II->isStr("push")) {
1306 if (Callbacks)
1308
1309 if (Tok.isNot(tok::eod))
1310 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1311 return;
1312 }
1313
1315 .Case("ignored", diag::Severity::Ignored)
1316 .Case("warning", diag::Severity::Warning)
1317 .Case("error", diag::Severity::Error)
1318 .Case("fatal", diag::Severity::Fatal)
1320
1322 PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
1323 return;
1324 }
1325
1326
1328 std::string WarningName;
1330 false))
1331 return;
1332
1333 if (Tok.isNot(tok::eod)) {
1334 PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
1335 return;
1336 }
1337
1338 if (WarningName.size() < 3 || WarningName[0] != '-' ||
1339 (WarningName[1] != 'W' && WarningName[1] != 'R')) {
1340 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
1341 return;
1342 }
1343
1344 diag::Flavor Flavor = WarningName[1] == 'W' ? diag::Flavor::WarningOrError
1345 : diag::Flavor::Remark;
1346 StringRef Group = StringRef(WarningName).substr(2);
1347 bool unknownDiag = false;
1348 if (Group == "everything") {
1349
1350
1351
1353 } else
1355 DiagLoc);
1356 if (unknownDiag)
1357 PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
1358 << WarningName;
1359 else if (Callbacks)
1360 Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
1361 }
1362};
1363
1364
1365struct PragmaHdrstopHandler : public PragmaHandler {
1366 PragmaHdrstopHandler() : PragmaHandler("hdrstop") {}
1368 Token &DepToken) override {
1370 }
1371};
1372
1373
1374
1375
1376struct PragmaWarningHandler : public PragmaHandler {
1377 PragmaWarningHandler() : PragmaHandler("warning") {}
1378
1380 Token &Tok) override {
1381
1382
1383
1384
1387
1388 PP.Lex(Tok);
1389 if (Tok.isNot(tok::l_paren)) {
1390 PP.Diag(Tok, diag::warn_pragma_warning_expected) << "(";
1391 return;
1392 }
1393
1394 PP.Lex(Tok);
1396
1397 if (II && II->isStr("push")) {
1398
1400 PP.Lex(Tok);
1401 if (Tok.is(tok::comma)) {
1402 PP.Lex(Tok);
1404 if (Tok.is(tok::numeric_constant) &&
1407 if (Level < 0 || Level > 4) {
1408 PP.Diag(Tok, diag::warn_pragma_warning_push_level);
1409 return;
1410 }
1411 }
1413 if (Callbacks)
1415 } else if (II && II->isStr("pop")) {
1416
1417 PP.Lex(Tok);
1419 PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
1420 else if (Callbacks)
1422 } else {
1423
1424
1425 while (true) {
1427 if (!II && !Tok.is(tok::numeric_constant)) {
1428 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1429 return;
1430 }
1431
1432
1433 bool SpecifierValid;
1435 if (II) {
1436 int SpecifierInt = llvm::StringSwitch(II->getName())
1442 .Default(-1);
1443 SpecifierValid = SpecifierInt != -1;
1444 if (SpecifierValid)
1447
1448
1449
1450 if (SpecifierValid)
1451 PP.Lex(Tok);
1452 } else {
1453
1456 if ((SpecifierValid = (Value >= 1) && (Value <= 4)))
1459 } else
1460 SpecifierValid = false;
1461
1462 }
1463
1464 if (!SpecifierValid) {
1465 PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
1466 return;
1467 }
1468 if (Tok.isNot(tok::colon)) {
1469 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
1470 return;
1471 }
1472
1473
1475 PP.Lex(Tok);
1476 while (Tok.is(tok::numeric_constant)) {
1480 PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
1481 return;
1482 }
1483 Ids.push_back(int(Value));
1484 }
1485
1486
1489 SV = diag::Severity::Ignored;
1491 for (int Id : Ids) {
1494 diag::Flavor::WarningOrError, *Group, SV, DiagLoc);
1495 assert(!unknownDiag &&
1496 "wd table should only contain known diags");
1497 (void)unknownDiag;
1498 }
1499 }
1500
1501 if (Callbacks)
1503
1504
1505 if (Tok.isNot(tok::semi))
1506 break;
1507 PP.Lex(Tok);
1508 }
1509 }
1510
1511 if (Tok.isNot(tok::r_paren)) {
1512 PP.Diag(Tok, diag::warn_pragma_warning_expected) << ")";
1513 return;
1514 }
1515
1516 PP.Lex(Tok);
1517 if (Tok.isNot(tok::eod))
1518 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma warning";
1519 }
1520};
1521
1522
1523
1524
1525struct PragmaExecCharsetHandler : public PragmaHandler {
1526 PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {}
1527
1529 Token &Tok) override {
1530
1531
1532
1535
1536 PP.Lex(Tok);
1537 if (Tok.isNot(tok::l_paren)) {
1538 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "(";
1539 return;
1540 }
1541
1542 PP.Lex(Tok);
1544
1545 if (II && II->isStr("push")) {
1546
1547 PP.Lex(Tok);
1548 if (Tok.is(tok::comma)) {
1549 PP.Lex(Tok);
1550
1551 std::string ExecCharset;
1553 "pragma execution_character_set",
1554 false))
1555 return;
1556
1557
1558 if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") {
1559 PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
1560 return;
1561 }
1562 }
1563 if (Callbacks)
1565 } else if (II && II->isStr("pop")) {
1566
1567 PP.Lex(Tok);
1568 if (Callbacks)
1570 } else {
1571 PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
1572 return;
1573 }
1574
1575 if (Tok.isNot(tok::r_paren)) {
1576 PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")";
1577 return;
1578 }
1579
1580 PP.Lex(Tok);
1581 if (Tok.isNot(tok::eod))
1582 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set";
1583 }
1584};
1585
1586
1587struct PragmaIncludeAliasHandler : public PragmaHandler {
1588 PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
1589
1591 Token &IncludeAliasTok) override {
1593 }
1594};
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609struct PragmaMessageHandler : public PragmaHandler {
1610private:
1613
1615 bool PragmaNameOnly = false) {
1616 switch (Kind) {
1618 return PragmaNameOnly ? "message" : "pragma message";
1620 return PragmaNameOnly ? "warning" : "pragma warning";
1622 return PragmaNameOnly ? "error" : "pragma error";
1623 }
1624 llvm_unreachable("Unknown PragmaMessageKind!");
1625 }
1626
1627public:
1629 StringRef Namespace = StringRef())
1632
1634 Token &Tok) override {
1636 PP.Lex(Tok);
1637 bool ExpectClosingParen = false;
1638 switch (Tok.getKind()) {
1639 case tok::l_paren:
1640
1641 ExpectClosingParen = true;
1642
1643 PP.Lex(Tok);
1644 break;
1645 case tok::string_literal:
1646
1647 break;
1648 default:
1649 PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
1650 return;
1651 }
1652
1653 std::string MessageString;
1655 true))
1656 return;
1657
1658 if (ExpectClosingParen) {
1659 if (Tok.isNot(tok::r_paren)) {
1661 return;
1662 }
1663 PP.Lex(Tok);
1664 }
1665
1666 if (Tok.isNot(tok::eod)) {
1668 return;
1669 }
1670
1671
1673 ? diag::err_pragma_message
1674 : diag::warn_pragma_message) << MessageString;
1675
1676
1678 Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
1679 }
1680};
1681
1682
1683
1684
1685
1686struct PragmaModuleImportHandler : public PragmaHandler {
1687 PragmaModuleImportHandler() : PragmaHandler("import") {}
1688
1690 Token &Tok) override {
1692
1693
1695 ModuleName;
1697 return;
1698
1699 if (Tok.isNot(tok::eod))
1700 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1701
1702
1705 false);
1706 if (!Imported)
1707 return;
1708
1711 tok::annot_module_include, Imported);
1713 CB->moduleImport(ImportLoc, ModuleName, Imported);
1714 }
1715};
1716
1717
1718
1719
1720
1721
1722
1723struct PragmaModuleBeginHandler : public PragmaHandler {
1724 PragmaModuleBeginHandler() : PragmaHandler("begin") {}
1725
1727 Token &Tok) override {
1729
1730
1732 ModuleName;
1734 return;
1735
1736 if (Tok.isNot(tok::eod))
1737 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1738
1739
1741 if (ModuleName.front().first->getName() != Current) {
1742 PP.Diag(ModuleName.front().second, diag::err_pp_module_begin_wrong_module)
1743 << ModuleName.front().first << (ModuleName.size() > 1)
1744 << Current.empty() << Current;
1745 return;
1746 }
1747
1748
1749
1751 auto &MM = HSI.getModuleMap();
1752 Module *M = HSI.lookupModule(Current, ModuleName.front().second);
1753 if (!M) {
1754 PP.Diag(ModuleName.front().second,
1755 diag::err_pp_module_begin_no_module_map) << Current;
1756 return;
1757 }
1758 for (unsigned I = 1; I != ModuleName.size(); ++I) {
1760 if (!NewM) {
1761 PP.Diag(ModuleName[I].second, diag::err_pp_module_begin_no_submodule)
1763 return;
1764 }
1765 M = NewM;
1766 }
1767
1768
1771 PP.Diag(BeginLoc, diag::note_pp_module_begin_here)
1773 return;
1774 }
1775
1776
1779 tok::annot_module_begin, M);
1780 }
1781};
1782
1783
1784struct PragmaModuleEndHandler : public PragmaHandler {
1785 PragmaModuleEndHandler() : PragmaHandler("end") {}
1786
1788 Token &Tok) override {
1790
1792 if (Tok.isNot(tok::eod))
1793 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1794
1796 if (M)
1798 else
1799 PP.Diag(Loc, diag::err_pp_module_end_without_module_begin);
1800 }
1801};
1802
1803
1804struct PragmaModuleBuildHandler : public PragmaHandler {
1805 PragmaModuleBuildHandler() : PragmaHandler("build") {}
1806
1808 Token &Tok) override {
1810 }
1811};
1812
1813
1814struct PragmaModuleLoadHandler : public PragmaHandler {
1815 PragmaModuleLoadHandler() : PragmaHandler("load") {}
1816
1818 Token &Tok) override {
1820
1821
1823 ModuleName;
1825 return;
1826
1827 if (Tok.isNot(tok::eod))
1828 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1829
1830
1832 false);
1833 }
1834};
1835
1836
1837
1838struct PragmaPushMacroHandler : public PragmaHandler {
1839 PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
1840
1842 Token &PushMacroTok) override {
1844 }
1845};
1846
1847
1848
1849struct PragmaPopMacroHandler : public PragmaHandler {
1850 PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
1851
1853 Token &PopMacroTok) override {
1855 }
1856};
1857
1858
1859
1860struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
1861 PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
1862
1864 Token &NameTok) override {
1866 bool IsBegin;
1867
1869
1870
1873 if (BeginEnd && BeginEnd->isStr("begin")) {
1874 IsBegin = true;
1875 } else if (BeginEnd && BeginEnd->isStr("end")) {
1876 IsBegin = false;
1877 } else {
1878 PP.Diag(Tok.getLocation(), diag::err_pp_arc_cf_code_audited_syntax);
1879 return;
1880 }
1881
1882
1884 if (Tok.isNot(tok::eod))
1885 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1886
1887
1889
1890
1892
1893 if (IsBegin) {
1894
1895 if (BeginLoc.isValid()) {
1896 PP.Diag(Loc, diag::err_pp_double_begin_of_arc_cf_code_audited);
1897 PP.Diag(BeginLoc, diag::note_pragma_entered_here);
1898 }
1899 NewLoc = Loc;
1900 } else {
1901
1902 if (!BeginLoc.isValid()) {
1903 PP.Diag(Loc, diag::err_pp_unmatched_end_of_arc_cf_code_audited);
1904 return;
1905 }
1907 }
1908
1910 }
1911};
1912
1913
1914
1915struct PragmaAssumeNonNullHandler : public PragmaHandler {
1916 PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}
1917
1919 Token &NameTok) override {
1921 bool IsBegin;
1922
1924
1925
1928 if (BeginEnd && BeginEnd->isStr("begin")) {
1929 IsBegin = true;
1930 } else if (BeginEnd && BeginEnd->isStr("end")) {
1931 IsBegin = false;
1932 } else {
1933 PP.Diag(Tok.getLocation(), diag::err_pp_assume_nonnull_syntax);
1934 return;
1935 }
1936
1937
1939 if (Tok.isNot(tok::eod))
1940 PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma";
1941
1942
1944
1945
1948
1949 if (IsBegin) {
1950
1951 if (BeginLoc.isValid()) {
1952 PP.Diag(Loc, diag::err_pp_double_begin_of_assume_nonnull);
1953 PP.Diag(BeginLoc, diag::note_pragma_entered_here);
1954 }
1955 NewLoc = Loc;
1956 if (Callbacks)
1958 } else {
1959
1960 if (!BeginLoc.isValid()) {
1961 PP.Diag(Loc, diag::err_pp_unmatched_end_of_assume_nonnull);
1962 return;
1963 }
1965 if (Callbacks)
1967 }
1968
1970 }
1971};
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984struct PragmaRegionHandler : public PragmaHandler {
1985 PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) {}
1986
1988 Token &NameTok) override {
1989
1990
1991
1992
1993 }
1994};
1995
1996
1997
1998
1999
2000
2002 PragmaManagedHandler(const char *pragma) : EmptyPragmaHandler(pragma) {}
2003};
2004
2005
2007 const char *Pragma,
2008 std::string &MessageString) {
2009 PP.Lex(Tok);
2010 if (Tok.isNot(tok::l_paren)) {
2011 PP.Diag(Tok, diag::err_expected) << "(";
2012 return nullptr;
2013 }
2014
2016 if (!Tok.is(tok::identifier)) {
2017 PP.Diag(Tok, diag::err_expected) << tok::identifier;
2018 return nullptr;
2019 }
2021
2023 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2024 return nullptr;
2025 }
2026
2027 PP.Lex(Tok);
2028 if (Tok.is(tok::comma)) {
2029 PP.Lex(Tok);
2031 true))
2032 return nullptr;
2033 }
2034
2035 if (Tok.isNot(tok::r_paren)) {
2036 PP.Diag(Tok, diag::err_expected) << ")";
2037 return nullptr;
2038 }
2039 return II;
2040}
2041
2042
2043
2044
2045
2046
2047
2048struct PragmaDeprecatedHandler : public PragmaHandler {
2049 PragmaDeprecatedHandler() : PragmaHandler("deprecated") {}
2050
2052 Token &Tok) override {
2053 std::string MessageString;
2054
2055 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2056 PP, Tok, "#pragma clang deprecated", MessageString)) {
2060 }
2061 }
2062};
2063
2064
2065
2066
2067
2068
2069
2070struct PragmaRestrictExpansionHandler : public PragmaHandler {
2071 PragmaRestrictExpansionHandler() : PragmaHandler("restrict_expansion") {}
2072
2074 Token &Tok) override {
2075 std::string MessageString;
2076
2077 if (IdentifierInfo *II = HandleMacroAnnotationPragma(
2078 PP, Tok, "#pragma clang restrict_expansion", MessageString)) {
2082 }
2083 }
2084};
2085
2086
2087
2088
2089
2090
2091
2092struct PragmaFinalHandler : public PragmaHandler {
2093 PragmaFinalHandler() : PragmaHandler("final") {}
2094
2096 Token &Tok) override {
2097 PP.Lex(Tok);
2098 if (Tok.isNot(tok::l_paren)) {
2099 PP.Diag(Tok, diag::err_expected) << "(";
2100 return;
2101 }
2102
2104 if (!Tok.is(tok::identifier)) {
2105 PP.Diag(Tok, diag::err_expected) << tok::identifier;
2106 return;
2107 }
2109
2111 PP.Diag(Tok, diag::err_pp_visibility_non_macro) << II;
2112 return;
2113 }
2114
2115 PP.Lex(Tok);
2116 if (Tok.isNot(tok::r_paren)) {
2117 PP.Diag(Tok, diag::err_expected) << ")";
2118 return;
2119 }
2122 }
2123};
2124
2125}
2126
2127
2128
2129void Preprocessor::RegisterBuiltinPragmas() {
2135
2136
2140 AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
2142 "GCC"));
2144 "GCC"));
2145
2150 AddPragmaHandler("clang", new PragmaDiagnosticHandler("clang"));
2151 AddPragmaHandler("clang", new PragmaARCCFCodeAuditedHandler());
2152 AddPragmaHandler("clang", new PragmaAssumeNonNullHandler());
2154 AddPragmaHandler("clang", new PragmaRestrictExpansionHandler());
2156
2157
2160 ModuleHandler->AddPragma(new PragmaModuleImportHandler());
2161 ModuleHandler->AddPragma(new PragmaModuleBeginHandler());
2162 ModuleHandler->AddPragma(new PragmaModuleEndHandler());
2163 ModuleHandler->AddPragma(new PragmaModuleBuildHandler());
2164 ModuleHandler->AddPragma(new PragmaModuleLoadHandler());
2165
2166
2167 AddPragmaHandler("clang", new PragmaUnsafeBufferUsageHandler);
2168
2169
2172
2173
2174 if (LangOpts.MicrosoftExt) {
2182 }
2183
2184
2185 for (const PragmaHandlerRegistry::entry &handler :
2186 PragmaHandlerRegistry::entries()) {
2188 }
2189}
2190
2191
2192
2195
2196
2199}
Defines the Diagnostic-related interfaces.
enum clang::sema::@1726::IndirectLocalPathEntry::EntryKind Kind
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the clang::Module class, which describes a module in the source code.
Defines the PPCallbacks interface.
static bool LexModuleName(Preprocessor &PP, Token &Tok, llvm::SmallVectorImpl< std::pair< IdentifierInfo *, SourceLocation > > &ModuleName)
static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, std::pair< IdentifierInfo *, SourceLocation > &ModuleNameComponent, bool First)
Defines the PreprocessorLexer interface.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines the clang::TokenKind enum and support functions.
const NestedNameSpecifier * Specifier
void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map, SourceLocation Loc=SourceLocation())
Add the specified mapping to all diagnostics of the specified flavor.
LLVM_DUMP_METHOD void dump() const
void pushMappings(SourceLocation Loc)
Copies the current DiagMappings and pushes the new copy onto the top of the stack.
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group, diag::Severity Map, SourceLocation Loc=SourceLocation())
Change an entire diagnostic group (e.g.
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
EmptyPragmaHandler - A pragma handler which takes no action, which can be used to ignore particular p...
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken) override
EmptyPragmaHandler(StringRef Name=StringRef())
time_t getModificationTime() const
One of these records is kept for each identifier that is lexed.
void setIsRestrictExpansion(bool Val)
void setIsDeprecatedMacro(bool Val)
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
void setIsFinal(bool Val)
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
bool isPoisoned() const
Return true if this token has been poisoned.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
StringRef getName() const
Return the actual identifier string.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static Lexer * Create_PragmaLexer(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLen, Preprocessor &PP)
Create_PragmaLexer: Lexer constructor - Create a new lexer object for _Pragma expansion.
Encapsulates the data about a macro definition (e.g.
void setIsAllowRedefinitionsWithoutWarning(bool Val)
Set the value of the IsAllowRedefinitionsWithoutWarning flag.
virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0
Attempt to load the given module.
virtual void createModuleFromSource(SourceLocation Loc, StringRef ModuleName, StringRef Source)=0
Attempt to create the given module from the specified source buffer.
Module * lookupModuleQualified(StringRef Name, Module *Context) const
Retrieve a module with the given name within the given context, using direct (qualified) name lookup.
Module * findOrInferSubmodule(Module *Parent, StringRef Name)
llvm::iterator_range< module_iterator > modules() const
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
llvm::iterator_range< submodule_iterator > submodules()
void dump() const
Dump the contents of this module to the given output stream.
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
This interface provides a way to observe the actions of the preprocessor as it does its thing.
virtual void PragmaExecCharsetPop(SourceLocation Loc)
Callback invoked when a #pragma execution_character_set(pop) directive is read.
virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic push directive is read.
virtual void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec, ArrayRef< int > Ids)
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType)
Callback invoked when a #pragma clang __debug directive is read.
virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str)
Callback invoked when a #pragma gcc diagnostic directive is read.
PragmaWarningSpecifier
Callback invoked when a #pragma warning directive is read.
virtual void PragmaAssumeNonNullEnd(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull end directive is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc)
Callback invoked when a #pragma clang assume_nonnull begin directive is read.
virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, PragmaMessageKind Kind, StringRef Str)
Callback invoked when a #pragma message directive is read.
virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str)
Callback invoked when a #pragma execution_character_set(push) directive is read.
virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace)
Callback invoked when a #pragma gcc diagnostic pop directive is read.
virtual void PragmaWarningPop(SourceLocation Loc)
Callback invoked when a #pragma warning(pop) directive is read.
PragmaMessageKind
Determines the kind of #pragma invoking a call to PragmaMessage.
@ PMK_Warning
#pragma GCC warning has been invoked.
@ PMK_Error
#pragma GCC error has been invoked.
@ PMK_Message
#pragma message has been invoked.
virtual void PragmaWarningPush(SourceLocation Loc, int Level)
Callback invoked when a #pragma warning(push) directive is read.
PragmaHandler - Instances of this interface defined to handle the various pragmas that the language f...
StringRef getName() const
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &FirstToken)=0
virtual PragmaNamespace * getIfNamespace()
getIfNamespace - If this is a namespace, return it.
PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...
void AddPragma(PragmaHandler *Handler)
AddPragma - Add a pragma to this namespace.
PragmaHandler * FindHandler(StringRef Name, bool IgnoreNull=true) const
FindHandler - Check to see if there is already a handler for the specified name.
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) override
void RemovePragmaHandler(PragmaHandler *Handler)
RemovePragmaHandler - Remove the given handler from the namespace.
PragmaNamespace * getIfNamespace() override
getIfNamespace - If this is a namespace, return it.
bool LexingRawMode
True if in raw mode.
bool ParsingPreprocessorDirective
True when parsing #XXX; turns '\n' into a tok::eod token.
OptionalFileEntryRef getFileEntry() const
getFileEntry - Return the FileEntry corresponding to this FileID.
bool DisablePragmaDebugCrash
Prevents intended crashes when using #pragma clang __debug. For testing.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void HandlePragmaPushMacro(Token &Tok)
Handle #pragma push_macro.
bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)
Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...
void HandlePragmaPoison()
HandlePragmaPoison - Handle #pragma GCC poison. PoisonTok is the 'poison'.
void dumpMacroInfo(const IdentifierInfo *II)
std::pair< IdentifierInfo *, SourceLocation > getPragmaARCCFCodeAuditedInfo() const
The location of the currently-active #pragma clang arc_cf_code_audited begin.
void HandlePragmaSystemHeader(Token &SysHeaderTok)
HandlePragmaSystemHeader - Implement #pragma GCC system_header.
void setPragmaARCCFCodeAuditedInfo(IdentifierInfo *Ident, SourceLocation Loc)
Set the location of the currently-active #pragma clang arc_cf_code_audited begin.
void HandlePragmaModuleBuild(Token &Tok)
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
void IgnorePragmas()
Install empty handlers for all pragmas (making them ignored).
PPCallbacks * getPPCallbacks() const
const MacroInfo * getMacroInfo(const IdentifierInfo *II) const
ArrayRef< BuildingSubmoduleInfo > getBuildingSubmodules() const
Get the list of submodules that we're currently building.
SourceLocation getModuleImportLoc(Module *M) const
void setPragmaAssumeNonNullLoc(SourceLocation Loc)
Set the location of the currently-active #pragma clang assume_nonnull begin.
bool isInPrimaryFile() const
Return true if we're in the top-level file, not in a #include.
void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())
Plop the specified string into a scratch buffer and set the specified token's location and length to ...
void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)
void addMacroDeprecationMsg(const IdentifierInfo *II, std::string Msg, SourceLocation AnnotationLoc)
void addRestrictExpansionMsg(const IdentifierInfo *II, std::string Msg, SourceLocation AnnotationLoc)
IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const
Given a tok::raw_identifier token, look up the identifier information for the token and install it in...
void addFinalLoc(const IdentifierInfo *II, SourceLocation AnnotationLoc)
void makeModuleVisible(Module *M, SourceLocation Loc)
void Lex(Token &Result)
Lex the next token for this preprocessor.
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
ModuleLoader & getModuleLoader() const
Retrieve the module loader associated with 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.
void HandlePragmaDependency(Token &DependencyTok)
HandlePragmaDependency - Handle #pragma GCC dependency "foo" blah.
SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)
Ensure that the next token is a tok::eod token.
bool enterOrExitSafeBufferOptOutRegion(bool isEnter, const SourceLocation &Loc)
Alter the state of whether this PP currently is in a "-Wunsafe-buffer-usage" opt-out region.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
void HandlePragmaOnce(Token &OnceTok)
HandlePragmaOnce - Handle #pragma once. OnceTok is the 'once'.
bool isMacroDefined(StringRef Id)
static bool checkModuleIsAvailable(const LangOptions &LangOpts, const TargetInfo &TargetInfo, const Module &M, DiagnosticsEngine &Diags)
Check that the given module is available, producing a diagnostic if not.
SourceLocation getPragmaAssumeNonNullLoc() const
The location of the currently-active #pragma clang assume_nonnull begin.
const TargetInfo & getTargetInfo() const
bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)
Lex a token, forming a header-name token if possible.
PreprocessorOptions & getPreprocessorOpts() const
Retrieve the preprocessor options used to initialize this preprocessor.
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.
bool creatingPCHWithPragmaHdrStop()
True if creating a PCH with a #pragma hdrstop.
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 ...
bool GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
Turn the specified lexer token into a fully checked and spelled filename, e.g.
PreprocessorLexer * getCurrentFileLexer() const
Return the current file lexer being lexed from.
HeaderSearch & getHeaderSearchInfo() const
void HandlePragmaPopMacro(Token &Tok)
Handle #pragma pop_macro.
Module * LeaveSubmodule(bool ForPragma)
void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)
Enter an annotation token into the token stream.
OptionalFileEntryRef LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled, ConstSearchDirIterator FromDir, const FileEntry *FromFile, ConstSearchDirIterator *CurDir, SmallVectorImpl< char > *SearchPath, SmallVectorImpl< char > *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache=false, bool OpenFile=true, bool CacheFailures=true)
Given a "foo" or reference, look up the indicated file.
const LangOptions & getLangOpts() const
IdentifierInfo * ParsePragmaPushOrPopMacro(Token &Tok)
ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
bool usingPCHWithPragmaHdrStop()
True if using a PCH with a #pragma hdrstop.
DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
void HandlePragmaMark(Token &MarkTok)
void HandlePragmaHdrstop(Token &Tok)
DiagnosticsEngine & getDiagnostics() const
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler)
Remove the specific pragma handler from this preprocessor.
void HandlePragmaIncludeAlias(Token &Tok)
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...
void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)
Add a directive to the macro directive history for this identifier.
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
void noteSLocAddressSpaceUsage(DiagnosticsEngine &Diag, std::optional< unsigned > MaxNotes=32) const
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
A trivial tuple used to represent a source range.
StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
bool hasUDSuffix() const
Return true if this token is a string or character literal which has a ud-suffix.
void setAnnotationRange(SourceRange R)
void startToken()
Reset all flags to cleared.
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...
uint32_t Literal
Literals are represented as positive integers.
Severity
Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs to either Ignore (nothing),...
Flavor
Flavors of diagnostics we can emit.
bool Sub(InterpState &S, CodePtr OpPC)
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
OnOffSwitch
Defines the possible values of an on-off-switch (C99 6.10.6p2).
The JSON file list parser is used to communicate input to InstallAPI.
std::optional< diag::Group > diagGroupFromCLWarningID(unsigned)
For cl.exe warning IDs that cleany map to clang diagnostic groups, returns the corresponding group.
@ Result
The result type of a method or function.
@ TU_Prefix
The translation unit is a prefix to a translation unit, and is not complete.
@ PIK__Pragma
The pragma was introduced via the C99 _Pragma(string-literal).
@ PIK___pragma
The pragma was introduced via the Microsoft __pragma(token-string).
void prepare_PragmaString(SmallVectorImpl< char > &StrVal)
Destringize a _Pragma("") string according to C11 6.10.9.1: "The string literal is destringized by de...
const FunctionProtoType * T
Describes how and where the pragma was introduced.
PragmaIntroducerKind Kind