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