clang: lib/Lex/Preprocessor.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

53#include "llvm/ADT/APInt.h"

54#include "llvm/ADT/ArrayRef.h"

55#include "llvm/ADT/DenseMap.h"

56#include "llvm/ADT/STLExtras.h"

57#include "llvm/ADT/SmallVector.h"

58#include "llvm/ADT/StringRef.h"

59#include "llvm/Support/Capacity.h"

60#include "llvm/Support/ErrorHandling.h"

61#include "llvm/Support/MemoryBuffer.h"

62#include "llvm/Support/raw_ostream.h"

63#include

64#include

65#include

66#include

67#include

68#include

69#include

70

71using namespace clang;

72

73

75

77

79

86 : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts),

87 FileMgr(Headers.getFileMgr()), SourceMgr(SM),

88 ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),

89 TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),

90

91

92

93 Identifiers(IILookup), PragmaHandlers(new PragmaNamespace(StringRef())),

94 TUKind(TUKind), SkipMainFilePreamble(0, true),

95 CurSubmoduleState(&NullSubmoduleState) {

96 OwnsHeaderSearch = OwnsHeaders;

97

98

99 KeepComments = false;

100 KeepMacroComments = false;

101 SuppressIncludeNotFoundError = false;

102

103

104 DisableMacroExpansion = false;

105 MacroExpansionInDirectivesOverride = false;

106 InMacroArgs = false;

107 ArgMacro = nullptr;

108 InMacroArgPreExpansion = false;

109 NumCachedTokenLexers = 0;

110 PragmasEnabled = true;

111 ParsingIfOrElifDirective = false;

112 PreprocessedOutput = false;

113

114

115 ReadMacrosFromExternalSource = false;

116

117 BuiltinInfo = std::make_uniqueBuiltin::Context();

118

119

120

121 (Ident__VA_ARGS__ = getIdentifierInfo("__VA_ARGS__"))->setIsPoisoned();

122 SetPoisonReason(Ident__VA_ARGS__,diag::ext_pp_bad_vaargs_use);

123 (Ident__VA_OPT__ = getIdentifierInfo("__VA_OPT__"))->setIsPoisoned();

124 SetPoisonReason(Ident__VA_OPT__,diag::ext_pp_bad_vaopt_use);

125

126

127 RegisterBuiltinPragmas();

128

129

130 RegisterBuiltinMacros();

131

132 if(LangOpts.Borland) {

135 Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation");

139 Ident__abnormal_termination = getIdentifierInfo("_abnormal_termination");

140 Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination");

141 Ident_AbnormalTermination = getIdentifierInfo("AbnormalTermination");

142 } else {

143 Ident__exception_info = Ident__exception_code = nullptr;

144 Ident__abnormal_termination = Ident___exception_info = nullptr;

145 Ident___exception_code = Ident___abnormal_termination = nullptr;

146 Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr;

147 Ident_AbnormalTermination = nullptr;

148 }

149

150

151

152 IncrementalProcessing = LangOpts.IncrementalExtensions;

153

154

156 SkippingUntilPragmaHdrStop = true;

157

158

159 if (!this->PPOpts->PCHThroughHeader.empty() &&

160 !this->PPOpts->ImplicitPCHInclude.empty())

161 SkippingUntilPCHThroughHeader = true;

162

163 if (this->PPOpts->GeneratePreamble)

164 PreambleConditionalStack.startRecording();

165

166 MaxTokens = LangOpts.MaxTokens;

167}

168

170 assert(isBacktrackEnabled() && "EnableBacktrack/Backtrack imbalance!");

171

172 IncludeMacroStack.clear();

173

174

175

176

177 std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr);

178 CurTokenLexer.reset();

179

180

181 for (MacroArgs *ArgList = MacroArgCache; ArgList;)

182 ArgList = ArgList->deallocate();

183

184

185 if (OwnsHeaderSearch)

186 delete &HeaderInfo;

187}

188

191 assert((!this->Target || this->Target == &Target) &&

192 "Invalid override of target information");

193 this->Target = &Target;

194

195 assert((!this->AuxTarget || this->AuxTarget == AuxTarget) &&

196 "Invalid override of aux target information.");

197 this->AuxTarget = AuxTarget;

198

199

200 BuiltinInfo->InitializeTarget(Target, AuxTarget);

202

203

205

206

208

210

212 else

213

215}

216

218 NumEnteredSourceFiles = 0;

219

220

221 PragmaHandlersBackup = std::move(PragmaHandlers);

222 PragmaHandlers = std::make_unique(StringRef());

223 RegisterBuiltinPragmas();

224

225

226 PredefinesFileID = FileID();

227}

228

230 NumEnteredSourceFiles = 1;

231

232 PragmaHandlers = std::move(PragmaHandlersBackup);

233}

234

237

239 llvm::errs() << " '" << getSpelling(Tok) << "'";

240

241 if (!DumpFlags) return;

242

243 llvm::errs() << "\t";

245 llvm::errs() << " [StartOfLine]";

247 llvm::errs() << " [LeadingSpace]";

249 llvm::errs() << " [ExpandDisabled]";

252 llvm::errs() << " [UnClean='" << StringRef(Start, Tok.getLength())

253 << "']";

254 }

255

256 llvm::errs() << "\tLoc=<";

258 llvm::errs() << ">";

259}

260

262 Loc.print(llvm::errs(), SourceMgr);

263}

264

266 llvm::errs() << "MACRO: ";

267 for (unsigned i = 0, e = MI.getNumTokens(); i != e; ++i) {

269 llvm::errs() << " ";

270 }

271 llvm::errs() << "\n";

272}

273

275 llvm::errs() << "\n*** Preprocessor Stats:\n";

276 llvm::errs() << NumDirectives << " directives found:\n";

277 llvm::errs() << " " << NumDefined << " #define.\n";

278 llvm::errs() << " " << NumUndefined << " #undef.\n";

279 llvm::errs() << " #include/#include_next/#import:\n";

280 llvm::errs() << " " << NumEnteredSourceFiles << " source files entered.\n";

281 llvm::errs() << " " << MaxIncludeStackDepth << " max include stack depth\n";

282 llvm::errs() << " " << NumIf << " #if/#ifndef/#ifdef.\n";

283 llvm::errs() << " " << NumElse << " #else/#elif/#elifdef/#elifndef.\n";

284 llvm::errs() << " " << NumEndif << " #endif.\n";

285 llvm::errs() << " " << NumPragma << " #pragma.\n";

286 llvm::errs() << NumSkipped << " #if/#ifndef#ifdef regions skipped\n";

287

288 llvm::errs() << NumMacroExpanded << "/" << NumFnMacroExpanded << "/"

289 << NumBuiltinMacroExpanded << " obj/fn/builtin macros expanded, "

290 << NumFastMacroExpanded << " on the fast path.\n";

291 llvm::errs() << (NumFastTokenPaste+NumTokenPaste)

292 << " token paste (##) operations performed, "

293 << NumFastTokenPaste << " on the fast path.\n";

294

295 llvm::errs() << "\nPreprocessor Memory: " << getTotalMemory() << "B total";

296

297 llvm::errs() << "\n BumpPtr: " << BP.getTotalMemory();

298 llvm::errs() << "\n Macro Expanded Tokens: "

299 << llvm::capacity_in_bytes(MacroExpandedTokens);

300 llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity();

301

302 llvm::errs() << "\n Macros: "

303 << llvm::capacity_in_bytes(CurSubmoduleState->Macros);

304 llvm::errs() << "\n #pragma push_macro Info: "

305 << llvm::capacity_in_bytes(PragmaPushMacroInfo);

306 llvm::errs() << "\n Poison Reasons: "

307 << llvm::capacity_in_bytes(PoisonReasons);

308 llvm::errs() << "\n Comment Handlers: "

309 << llvm::capacity_in_bytes(CommentHandlers) << "\n";

310}

311

315 !ReadMacrosFromExternalSource) {

316 ReadMacrosFromExternalSource = true;

318 }

319

320

321 for (const ModuleMacro &Macro : ModuleMacros)

322 CurSubmoduleState->Macros.insert(std::make_pair(Macro.II, MacroState()));

323

324 return CurSubmoduleState->Macros.begin();

325}

326

328 return BP.getTotalMemory()

329 + llvm::capacity_in_bytes(MacroExpandedTokens)

330 + Predefines.capacity()

331

332

333 + llvm::capacity_in_bytes(CurSubmoduleState->Macros)

334 + llvm::capacity_in_bytes(PragmaPushMacroInfo)

335 + llvm::capacity_in_bytes(PoisonReasons)

336 + llvm::capacity_in_bytes(CommentHandlers);

337}

338

342 !ReadMacrosFromExternalSource) {

343 ReadMacrosFromExternalSource = true;

345 }

346

347 return CurSubmoduleState->Macros.end();

348}

349

350

353 return Tokens.size() == MI->getNumTokens() &&

354 std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin());

355}

356

361 StringRef BestSpelling;

363 I != E; ++I) {

365 Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);

367 continue;

369 continue;

371 continue;

373

377 BestLocation = Location;

378 BestSpelling = I->first->getName();

379 }

380 }

381 return BestSpelling;

382}

383

385 if (CurLexer)

386 CurLexerCallback = CurLexer->isDependencyDirectivesLexer()

387 ? CLK_DependencyDirectivesLexer

388 : CLK_Lexer;

389 else if (CurTokenLexer)

390 CurLexerCallback = CLK_TokenLexer;

391 else

392 CurLexerCallback = CLK_CachingLexer;

393}

394

396 unsigned CompleteLine,

397 unsigned CompleteColumn) {

398 assert(CompleteLine && CompleteColumn && "Starts from 1:1");

399 assert(!CodeCompletionFile && "Already set");

400

401

402 std::optionalllvm::MemoryBufferRef Buffer =

404 if (!Buffer)

405 return true;

406

407

408 const char *Position = Buffer->getBufferStart();

409 for (unsigned Line = 1; Line < CompleteLine; ++Line) {

410 for (; *Position; ++Position) {

411 if (*Position != '\r' && *Position != '\n')

412 continue;

413

414

415 if ((Position[1] == '\r' || Position[1] == '\n') &&

416 Position[0] != Position[1])

417 ++Position;

418 ++Position;

419 break;

420 }

421 }

422

423 Position += CompleteColumn - 1;

424

425

426

427 if (SkipMainFilePreamble.first &&

429 if (Position - Buffer->getBufferStart() < SkipMainFilePreamble.first)

430 Position = Buffer->getBufferStart() + SkipMainFilePreamble.first;

431 }

432

433 if (Position > Buffer->getBufferEnd())

434 Position = Buffer->getBufferEnd();

435

436 CodeCompletionFile = File;

437 CodeCompletionOffset = Position - Buffer->getBufferStart();

438

439 auto NewBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(

440 Buffer->getBufferSize() + 1, Buffer->getBufferIdentifier());

441 char *NewBuf = NewBuffer->getBufferStart();

442 char *NewPos = std::copy(Buffer->getBufferStart(), Position, NewBuf);

443 *NewPos = '\0';

444 std::copy(Position, Buffer->getBufferEnd(), NewPos+1);

446

447 return false;

448}

449

451 bool IsAngled) {

453 if (CodeComplete)

455}

456

459 if (CodeComplete)

461}

462

463

464

465

469

470 if (Tok.isNot(tok::raw_identifier) && !Tok.hasUCN()) {

471

473 return II->getName();

474 }

475

476

479

480 const char *Ptr = Buffer.data();

482 return StringRef(Ptr, Len);

483}

484

485

486

487

492

493 const char *DestPtr;

494 SourceLocation Loc = ScratchBuf->getToken(Str.data(), Str.size(), DestPtr);

495

496 if (ExpansionLocStart.isValid())

498 ExpansionLocEnd, Str.size());

500

501

502 if (Tok.is(tok::raw_identifier))

506}

507

511 std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellingLoc);

513 StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);

516

517

518 const char *DestPtr;

520 ScratchBuf->getToken(Buffer.data() + LocInfo.second, Length, DestPtr);

522}

523

526 return nullptr;

527

529}

530

532 if (getLangOpts().isCompilingModuleImplementation())

533 return nullptr;

534

536}

537

538

539

540

541

542

543

545

546

547

548 assert(NumEnteredSourceFiles == 0 && "Cannot reenter the main file!");

550

551

552

554

556

557

558

559 if (SkipMainFilePreamble.first > 0)

560 CurLexer->SetByteOffset(SkipMainFilePreamble.first,

561 SkipMainFilePreamble.second);

562

563

564

567 }

568

569

570 std::unique_ptrllvm::MemoryBuffer SB =

571 llvm::MemoryBuffer::getMemBufferCopy(Predefines, "");

572 assert(SB && "Cannot create predefined source buffer");

574 assert(FID.isValid() && "Could not create FileID for predefines?");

575 setPredefinesFileID(FID);

576

577

579

580 if (!PPOpts->PCHThroughHeader.empty()) {

581

582

585 false, nullptr, nullptr,

586 nullptr, nullptr, nullptr,

587 nullptr, nullptr,

588 nullptr);

591 << PPOpts->PCHThroughHeader;

592 return;

593 }

594 setPCHThroughHeaderFileID(

596 }

597

598

602}

603

604void Preprocessor::setPCHThroughHeaderFileID(FileID FID) {

605 assert(PCHThroughHeaderFileID.isInvalid() &&

606 "PCHThroughHeaderFileID already set!");

607 PCHThroughHeaderFileID = FID;

608}

609

611 assert(PCHThroughHeaderFileID.isValid() &&

612 "Invalid PCH through header FileID");

613 return FE == SourceMgr.getFileEntryForID(PCHThroughHeaderFileID);

614}

615

617 return TUKind == TU_Prefix && !PPOpts->PCHThroughHeader.empty() &&

618 PCHThroughHeaderFileID.isValid();

619}

620

622 return TUKind != TU_Prefix && !PPOpts->PCHThroughHeader.empty() &&

623 PCHThroughHeaderFileID.isValid();

624}

625

628}

629

632}

633

634

635

636

637

638

640 bool ReachedMainFileEOF = false;

641 bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader;

642 bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop;

644 while (true) {

645 bool InPredefines =

647 CurLexerCallback(*this, Tok);

648 if (Tok.is(tok::eof) && !InPredefines) {

649 ReachedMainFileEOF = true;

650 break;

651 }

652 if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader)

653 break;

654 if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop)

655 break;

656 }

657 if (ReachedMainFileEOF) {

658 if (UsingPCHThroughHeader)

660 << PPOpts->PCHThroughHeader << 1;

661 else if (!PPOpts->PCHWithHdrStopCreate)

663 }

664}

665

666void Preprocessor::replayPreambleConditionalStack() {

667

668 if (PreambleConditionalStack.isReplaying()) {

669 assert(CurPPLexer &&

670 "CurPPLexer is null when calling replayPreambleConditionalStack.");

672 PreambleConditionalStack.doneReplaying();

673 if (PreambleConditionalStack.reachedEOFWhileSkipping())

674 SkipExcludedConditionalBlock(

675 PreambleConditionalStack.SkipInfo->HashTokenLoc,

676 PreambleConditionalStack.SkipInfo->IfTokenLoc,

677 PreambleConditionalStack.SkipInfo->FoundNonSkipPortion,

678 PreambleConditionalStack.SkipInfo->FoundElse,

679 PreambleConditionalStack.SkipInfo->ElseLoc);

680 }

681}

682

684

685 if (Callbacks)

686 Callbacks->EndOfMainFile();

687}

688

689

690

691

692

693

694

695

697 assert(Identifier.getRawIdentifier().empty() && "No raw identifier data!");

698

699

702

704 } else {

705

708

711 expandUCNs(UCNIdentifierBuffer, CleanedStr);

713 } else {

715 }

716 }

717

718

719

720

721

722

723

724

727

728 return II;

729}

730

732 PoisonReasons[II] = DiagID;

733}

734

736 assert(Ident__exception_code && Ident__exception_info);

737 assert(Ident___exception_code && Ident___exception_info);

744 Ident__abnormal_termination->setIsPoisoned(Poison);

745 Ident___abnormal_termination->setIsPoisoned(Poison);

746 Ident_AbnormalTermination->setIsPoisoned(Poison);

747}

748

750 assert(Identifier.getIdentifierInfo() &&

751 "Can't handle identifiers without identifier info!");

752 llvm::DenseMap<IdentifierInfo*,unsigned>::const_iterator it =

753 PoisonReasons.find(Identifier.getIdentifierInfo());

754 if(it == PoisonReasons.end())

756 else

758}

759

760void Preprocessor::updateOutOfDateIdentifier(const IdentifierInfo &II) const {

761 assert(II.isOutOfDate() && "not out of date");

763}

764

765

766

767

768

769

770

771

772

774 assert(Identifier.getIdentifierInfo() &&

775 "Can't handle identifiers without identifier info!");

776

778

779

780

781

782

783

785 bool CurrentIsPoisoned = false;

786 const bool IsSpecialVariadicMacro =

787 &II == Ident__VA_ARGS__ || &II == Ident__VA_OPT__;

788 if (IsSpecialVariadicMacro)

790

791 updateOutOfDateIdentifier(II);

793

794 if (IsSpecialVariadicMacro)

796 }

797

798

799

802 }

803

804

806 const auto *MI = MD.getMacroInfo();

807 assert(MI && "macro definition with no macro info?");

808 if (!DisableMacroExpansion) {

809 if (Identifier.isExpandDisabled() && MI->isEnabled()) {

810

811

812 if (!MI->isFunctionLike() || isNextPPTokenLParen())

813 return HandleMacroExpandedIdentifier(Identifier, MD);

814 } else {

815

816

817

819 if (MI->isObjectLike() || isNextPPTokenLParen())

821 }

822 }

823 }

824

825

826

827

828

829

833

835 }

836

837

838

839

840

843

844

845

846

847

848

849

850

851

854 !InMacroArgs && !DisableMacroExpansion &&

856 CurLexerCallback != CLK_CachingLexer) {

857 ModuleImportLoc = Identifier.getLocation();

858 NamedModuleImportPath.clear();

859 IsAtImport = true;

860 ModuleImportExpectsIdentifier = true;

861 CurLexerCallback = CLK_LexAfterModuleImport;

862 }

863 return true;

864}

865

867 ++LexLevel;

868

869

870 while (!CurLexerCallback(*this, Result))

871 ;

872

874 return;

875

876 if (Result.is(tok::code_completion) && Result.getIdentifierInfo()) {

877

880

881

882 Result.setIdentifierInfo(nullptr);

883 }

884

885

886

887

888

889

890 if (getLangOpts().CPlusPlusModules && LexLevel == 1 &&

892 switch (Result.getKind()) {

893 case tok::l_paren: case tok::l_square: case tok::l_brace:

894 StdCXXImportSeqState.handleOpenBracket();

895 break;

896 case tok::r_paren: case tok::r_square:

897 StdCXXImportSeqState.handleCloseBracket();

898 break;

899 case tok::r_brace:

900 StdCXXImportSeqState.handleCloseBrace();

901 break;

902#define PRAGMA_ANNOTATION(X) case tok::annot_##X:

903

904#include "clang/Basic/TokenKinds.def"

905#undef PRAGMA_ANNOTATION

906

907

908 case tok::annot_module_include:

909 case tok:🚛

910 TrackGMFState.handleSemi();

911 StdCXXImportSeqState.handleSemi();

912 ModuleDeclState.handleSemi();

913 break;

914 case tok::header_name:

915 case tok::annot_header_unit:

916 StdCXXImportSeqState.handleHeaderName();

917 break;

918 case tok::kw_export:

919 TrackGMFState.handleExport();

920 StdCXXImportSeqState.handleExport();

921 ModuleDeclState.handleExport();

922 break;

923 case tok::colon:

924 ModuleDeclState.handleColon();

925 break;

926 case tok::period:

927 ModuleDeclState.handlePeriod();

928 break;

929 case tok::identifier:

930

931

932 if (StdCXXImportSeqState.atTopLevel()) {

933 if (Result.getIdentifierInfo()->isModulesImport()) {

934 TrackGMFState.handleImport(StdCXXImportSeqState.afterTopLevelSeq());

935 StdCXXImportSeqState.handleImport();

936 if (StdCXXImportSeqState.afterImportSeq()) {

937 ModuleImportLoc = Result.getLocation();

938 NamedModuleImportPath.clear();

939 IsAtImport = false;

940 ModuleImportExpectsIdentifier = true;

941 CurLexerCallback = CLK_LexAfterModuleImport;

942 }

943 break;

945 TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq());

946 ModuleDeclState.handleModule();

947 break;

948 }

949 }

950 ModuleDeclState.handleIdentifier(Result.getIdentifierInfo());

951 if (ModuleDeclState.isModuleCandidate())

952 break;

953 [[fallthrough]];

954 default:

955 TrackGMFState.handleMisc();

956 StdCXXImportSeqState.handleMisc();

957 ModuleDeclState.handleMisc();

958 break;

959 }

960 }

961

963 CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr);

964 CheckPointCounter = 0;

965 }

966

967 LastTokenWasAt = Result.is(tok::at);

968 --LexLevel;

969

970 if ((LexLevel == 0 || PreprocessToken) &&

972 if (LexLevel == 0)

973 ++TokenCount;

974 if (OnToken)

976 }

977}

978

980 while (1) {

982 Lex(Tok);

983 if (Tok.isOneOf(tok::unknown, tok::eof, tok::eod,

984 tok::annot_repl_input_end))

985 break;

986 if (Tokens != nullptr)

987 Tokens->push_back(Tok);

988 }

989}

990

991

992

993

994

995

996

997

998

999

1000

1001

1003

1004

1005 if (CurPPLexer)

1007 else

1008 Lex(FilenameTok);

1009

1010

1011

1013 if (FilenameTok.is(tok::less) && AllowMacroExpansion) {

1017

1020 FilenameBuffer.push_back('<');

1021

1022

1023

1024

1025

1026 while (FilenameTok.isNot(tok::greater)) {

1027 Lex(FilenameTok);

1028 if (FilenameTok.isOneOf(tok::eod, tok::eof)) {

1029 Diag(FilenameTok.getLocation(), diag::err_expected) << tok::greater;

1030 Diag(Start, diag::note_matching) << tok::less;

1031 return true;

1032 }

1033

1035

1036

1037 if (FilenameTok.is(tok::code_completion)) {

1039 Lex(FilenameTok);

1040 continue;

1041 }

1042

1043

1044

1046 FilenameBuffer.push_back(' ');

1047

1048

1049

1050 size_t PreAppendSize = FilenameBuffer.size();

1051 FilenameBuffer.resize(PreAppendSize + FilenameTok.getLength());

1052

1053 const char *BufPtr = &FilenameBuffer[PreAppendSize];

1054 unsigned ActualLen = getSpelling(FilenameTok, BufPtr);

1055

1056

1057 if (BufPtr != &FilenameBuffer[PreAppendSize])

1058 memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);

1059

1060

1061 if (FilenameTok.getLength() != ActualLen)

1062 FilenameBuffer.resize(PreAppendSize + ActualLen);

1063 }

1064

1066 FilenameTok.setKind(tok::header_name);

1070 CreateString(FilenameBuffer, FilenameTok, Start, End);

1071 } else if (FilenameTok.is(tok::string_literal) && AllowMacroExpansion) {

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082 StringRef Str = getSpelling(FilenameTok, FilenameBuffer);

1083 if (Str.size() >= 2 && Str.front() == '"' && Str.back() == '"')

1084 FilenameTok.setKind(tok::header_name);

1085 }

1086

1087 return false;

1088}

1089

1090

1092

1093

1094

1095 unsigned BracketDepth = 0;

1096 while (true) {

1097 Toks.emplace_back();

1098 Lex(Toks.back());

1099

1100 switch (Toks.back().getKind()) {

1101 case tok::l_paren: case tok::l_square: case tok::l_brace:

1102 ++BracketDepth;

1103 break;

1104

1105 case tok::r_paren: case tok::r_square: case tok::r_brace:

1106 if (BracketDepth == 0)

1107 return;

1108 --BracketDepth;

1109 break;

1110

1111 case tok:🚛

1112 if (BracketDepth == 0)

1113 return;

1114 break;

1115

1116 case tok::eof:

1117 return;

1118

1119 default:

1120 break;

1121 }

1122 }

1123}

1124

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1146

1148

1149

1150

1151

1152

1153

1154

1155 if (NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules) {

1157 return true;

1158

1159 if (Result.is(tok::colon) && ModuleDeclState.isNamedModule()) {

1160 std::string Name = ModuleDeclState.getPrimaryName().str();

1161 Name += ":";

1162 NamedModuleImportPath.push_back(

1164 CurLexerCallback = CLK_LexAfterModuleImport;

1165 return true;

1166 }

1167 } else {

1169 }

1170

1171

1172

1174 auto ToksCopy = std::make_unique<Token[]>(Toks.size());

1175 std::copy(Toks.begin(), Toks.end(), ToksCopy.get());

1176 EnterTokenStream(std::move(ToksCopy), Toks.size(),

1177 true, false);

1178 };

1179

1180 bool ImportingHeader = Result.is(tok::header_name);

1181

1183 if (ImportingHeader) {

1184

1185

1186

1187 Suffix.push_back(Result);

1188

1189

1190

1192 if (Suffix.back().isNot(tok::semi)) {

1193

1194 EnterTokens(Suffix);

1195 return false;

1196 }

1197

1198

1199

1200

1201 SourceLocation SemiLoc = Suffix.back().getLocation();

1203 Diag(SemiLoc, diag::err_header_import_semi_in_macro);

1204

1205

1206 Token ImportTok;

1208 ImportTok.setKind(tok::kw_import);

1212

1213 auto Action = HandleHeaderIncludeOrImport(

1214 SourceLocation(), ImportTok, Suffix.front(), SemiLoc);

1215 switch (Action.Kind) {

1216 case ImportAction::None:

1217 break;

1218

1219 case ImportAction::ModuleBegin:

1220

1221 Suffix.emplace_back();

1222 Suffix.back().startToken();

1223 Suffix.back().setKind(tok::annot_module_begin);

1224 Suffix.back().setLocation(SemiLoc);

1225 Suffix.back().setAnnotationEndLoc(SemiLoc);

1226 Suffix.back().setAnnotationValue(Action.ModuleForHeader);

1227 [[fallthrough]];

1228

1229 case ImportAction::ModuleImport:

1230 case ImportAction::HeaderUnitImport:

1231 case ImportAction::SkippedModuleImport:

1232

1233

1234 Suffix[0].setKind(tok::annot_header_unit);

1235 Suffix[0].setAnnotationEndLoc(Suffix[0].getLocation());

1236 Suffix[0].setAnnotationValue(Action.ModuleForHeader);

1237

1238 break;

1239 case ImportAction::Failure:

1241 "This should be an early exit only to a fatal error");

1242 Result.setKind(tok::eof);

1243 CurLexer->cutOffLexing();

1244 EnterTokens(Suffix);

1245 return true;

1246 }

1247

1248 EnterTokens(Suffix);

1249 return false;

1250 }

1251

1252

1253

1254

1255

1256

1257

1258 if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) {

1259

1260

1261 NamedModuleImportPath.push_back(

1262 std::make_pair(Result.getIdentifierInfo(), Result.getLocation()));

1263 ModuleImportExpectsIdentifier = false;

1264 CurLexerCallback = CLK_LexAfterModuleImport;

1265 return true;

1266 }

1267

1268

1269

1270

1271 if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {

1272 ModuleImportExpectsIdentifier = true;

1273 CurLexerCallback = CLK_LexAfterModuleImport;

1274 return true;

1275 }

1276

1277

1278 if (NamedModuleImportPath.empty() || Result.is(tok::eof))

1279 return true;

1280

1281

1282

1284 if (Result.isNot(tok::semi)) {

1285 Suffix.push_back(Result);

1287 if (Suffix.back().isNot(tok::semi)) {

1288

1289 EnterTokens(Suffix);

1290 return false;

1291 }

1292 SemiLoc = Suffix.back().getLocation();

1293 }

1294

1295

1296

1297

1298

1299 std::string FlatModuleName;

1301 for (auto &Piece : NamedModuleImportPath) {

1302

1303 if (!FlatModuleName.empty() && FlatModuleName.back() != ':')

1304 FlatModuleName += ".";

1305 FlatModuleName += Piece.first->getName();

1306 }

1307 SourceLocation FirstPathLoc = NamedModuleImportPath[0].second;

1308 NamedModuleImportPath.clear();

1309 NamedModuleImportPath.push_back(

1310 std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));

1311 }

1312

1313 Module *Imported = nullptr;

1314

1316 Imported = TheModuleLoader.loadModule(ModuleImportLoc,

1317 NamedModuleImportPath,

1319 false);

1320 if (Imported)

1322 }

1323

1324 if (Callbacks)

1325 Callbacks->moduleImport(ModuleImportLoc, NamedModuleImportPath, Imported);

1326

1327 if (!Suffix.empty()) {

1328 EnterTokens(Suffix);

1329 return false;

1330 }

1331 return true;

1332}

1333

1335 CurSubmoduleState->VisibleModules.setVisible(

1338

1339

1340 Diag(ModuleImportLoc, diag::warn_module_conflict)

1341 << Path[0]->getFullModuleName()

1342 << Conflict->getFullModuleName()

1343 << Message;

1344 });

1345

1346

1347 if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M)

1348 BuildingSubmoduleStack.back().M->Imports.insert(M);

1349}

1350

1352 const char *DiagnosticTag,

1353 bool AllowMacroExpansion) {

1354

1355 if (Result.isNot(tok::string_literal)) {

1356 Diag(Result, diag::err_expected_string_literal)

1357 << 0 << DiagnosticTag;

1358 return false;

1359 }

1360

1361

1363 do {

1364 StrToks.push_back(Result);

1365

1366 if (Result.hasUDSuffix())

1367 Diag(Result, diag::err_invalid_string_udl);

1368

1369 if (AllowMacroExpansion)

1371 else

1373 } while (Result.is(tok::string_literal));

1374

1375

1377 assert(Literal.isOrdinary() && "Didn't allow wide strings in");

1378

1379 if (Literal.hadError)

1380 return false;

1381

1382 if (Literal.Pascal) {

1383 Diag(StrToks[0].getLocation(), diag::err_expected_string_literal)

1384 << 0 << DiagnosticTag;

1385 return false;

1386 }

1387

1388 String = std::string(Literal.GetString());

1389 return true;

1390}

1391

1393 assert(Tok.is(tok::numeric_constant));

1395 bool NumberInvalid = false;

1396 StringRef Spelling = getSpelling(Tok, IntegerBuffer, &NumberInvalid);

1397 if (NumberInvalid)

1398 return false;

1402 if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix())

1403 return false;

1404 llvm::APInt APVal(64, 0);

1405 if (Literal.GetIntegerValue(APVal))

1406 return false;

1407 Lex(Tok);

1408 Value = APVal.getLimitedValue();

1409 return true;

1410}

1411

1413 assert(Handler && "NULL comment handler");

1414 assert(!llvm::is_contained(CommentHandlers, Handler) &&

1415 "Comment handler already registered");

1416 CommentHandlers.push_back(Handler);

1417}

1418

1420 std::vector<CommentHandler *>::iterator Pos =

1421 llvm::find(CommentHandlers, Handler);

1422 assert(Pos != CommentHandlers.end() && "Comment handler not registered");

1423 CommentHandlers.erase(Pos);

1424}

1425

1427 bool AnyPendingTokens = false;

1428 for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(),

1429 HEnd = CommentHandlers.end();

1430 H != HEnd; ++H) {

1431 if ((*H)->HandleComment(*this, Comment))

1432 AnyPendingTokens = true;

1433 }

1435 return false;

1436 Lex(result);

1437 return true;

1438}

1439

1440void Preprocessor::emitMacroDeprecationWarning(const Token &Identifier) const {

1441 const MacroAnnotations &A =

1443 assert(A.DeprecationInfo &&

1444 "Macro deprecation warning without recorded annotation!");

1445 const MacroAnnotationInfo &Info = *A.DeprecationInfo;

1446 if (Info.Message.empty())

1447 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)

1448 << Identifier.getIdentifierInfo() << 0;

1449 else

1450 Diag(Identifier, diag::warn_pragma_deprecated_macro_use)

1451 << Identifier.getIdentifierInfo() << 1 << Info.Message;

1452 Diag(Info.Location, diag::note_pp_macro_annotation) << 0;

1453}

1454

1455void Preprocessor::emitRestrictExpansionWarning(const Token &Identifier) const {

1456 const MacroAnnotations &A =

1458 assert(A.RestrictExpansionInfo &&

1459 "Macro restricted expansion warning without recorded annotation!");

1460 const MacroAnnotationInfo &Info = *A.RestrictExpansionInfo;

1461 if (Info.Message.empty())

1462 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)

1463 << Identifier.getIdentifierInfo() << 0;

1464 else

1465 Diag(Identifier, diag::warn_pragma_restrict_expansion_macro_use)

1466 << Identifier.getIdentifierInfo() << 1 << Info.Message;

1467 Diag(Info.Location, diag::note_pp_macro_annotation) << 1;

1468}

1469

1470void Preprocessor::emitRestrictInfNaNWarning(const Token &Identifier,

1471 unsigned DiagSelection) const {

1472 Diag(Identifier, diag::warn_fp_nan_inf_when_disabled) << DiagSelection << 1;

1473}

1474

1475void Preprocessor::emitFinalMacroWarning(const Token &Identifier,

1476 bool IsUndef) const {

1477 const MacroAnnotations &A =

1479 assert(A.FinalAnnotationLoc &&

1480 "Final macro warning without recorded annotation!");

1481

1483 << Identifier.getIdentifierInfo() << (IsUndef ? 0 : 1);

1484 Diag(*A.FinalAnnotationLoc, diag::note_pp_macro_annotation) << 2;

1485}

1486

1489

1490

1493

1494 auto FirstRegionEndingAfterLoc = llvm::partition_point(

1495 Map, [&SourceMgr,

1496 &Loc](const std::pair<SourceLocation, SourceLocation> &Region) {

1498 });

1499

1500 if (FirstRegionEndingAfterLoc != Map.end()) {

1501

1503 FirstRegionEndingAfterLoc->first, Loc);

1504 }

1505

1506

1507 if (!Map.empty() && Map.back().first == Map.back().second)

1509 return false;

1510 };

1511

1512

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1531 return TestInMap(SafeBufferOptOutMap, Loc);

1532

1534 LoadedSafeBufferOptOutMap.lookupLoadedOptOutMap(Loc, SourceMgr);

1535

1538 return false;

1539}

1540

1543 if (isEnter) {

1545 return true;

1546 InSafeBufferOptOutRegion = true;

1547 CurrentSafeBufferOptOutStart = Loc;

1548

1549

1550

1551 if (!SafeBufferOptOutMap.empty()) {

1552 [[maybe_unused]] auto *PrevRegion = &SafeBufferOptOutMap.back();

1553 assert(PrevRegion->first != PrevRegion->second &&

1554 "Shall not begin a safe buffer opt-out region before closing the "

1555 "previous one.");

1556 }

1557

1558

1559

1560 SafeBufferOptOutMap.emplace_back(Loc, Loc);

1561 } else {

1563 return true;

1564 InSafeBufferOptOutRegion = false;

1565

1566

1567

1568 assert(!SafeBufferOptOutMap.empty() &&

1569 "Misordered safe buffer opt-out regions");

1570 auto *CurrRegion = &SafeBufferOptOutMap.back();

1571 assert(CurrRegion->first == CurrRegion->second &&

1572 "Set end location to a closed safe buffer opt-out region");

1573 CurrRegion->second = Loc;

1574 }

1575 return false;

1576}

1577

1579 return InSafeBufferOptOutRegion;

1580}

1582 StartLoc = CurrentSafeBufferOptOutStart;

1583 return InSafeBufferOptOutRegion;

1584}

1585

1588 assert(!InSafeBufferOptOutRegion &&

1589 "Attempt to serialize safe buffer opt-out regions before file being "

1590 "completely preprocessed");

1591

1593

1594 for (const auto &[begin, end] : SafeBufferOptOutMap) {

1595 SrcSeq.push_back(begin);

1596 SrcSeq.push_back(end);

1597 }

1598

1599

1600

1601

1602

1603 return SrcSeq;

1604}

1605

1608 if (SourceLocations.size() == 0)

1609 return false;

1610

1611 assert(SourceLocations.size() % 2 == 0 &&

1612 "ill-formed SourceLocation sequence");

1613

1614 auto It = SourceLocations.begin();

1616 LoadedSafeBufferOptOutMap.findAndConsLoadedOptOutMap(*It, SourceMgr);

1617

1618 do {

1621

1622 Regions.emplace_back(Begin, End);

1623 } while (It != SourceLocations.end());

1624 return true;

1625}

1626

1628

1630

1632

1634

1637 return;

1638

1641}

1642

1644 if (auto It = CheckPoints.find(FID); It != CheckPoints.end()) {

1646 const char *Last = nullptr;

1647

1648 for (const char *P : FileCheckPoints) {

1649 if (P > Start)

1650 break;

1652 }

1653 return Last;

1654 }

1655

1656 return nullptr;

1657}

Defines enum values for all the target-independent builtin functions.

Defines the clang::FileManager interface and associated types.

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.

llvm::MachO::Target Target

llvm::MachO::Record Record

Defines the clang::MacroInfo and clang::MacroDirective classes.

Defines the clang::Module class, which describes a module in the source code.

Defines the PreprocessorLexer interface.

static bool MacroDefinitionEquals(const MacroInfo *MI, ArrayRef< TokenValue > Tokens)

Compares macro tokens with a specified token value sequence.

static constexpr unsigned CheckPointStepSize

Minimum distance between two check points, in tokens.

Defines the clang::Preprocessor interface.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

virtual void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)

Callback invoked when performing code completion inside the filename part of an #include directive.

virtual ~CodeCompletionHandler()

virtual void CodeCompleteNaturalLanguage()

Callback invoked when performing code completion in a part of the file where we expect natural langua...

Concrete class used by the front-end to report problems and issues.

virtual ~EmptylineHandler()

virtual ~ExternalPreprocessorSource()

virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0

Update an out-of-date identifier.

A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...

Cached information about one file (either on disk or in the virtual file system).

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

Provides lookups to, and iteration over, IdentiferInfo objects.

One of these records is kept for each identifier that is lexed.

bool isModulesImport() const

Determine whether this is the contextual keyword import.

tok::TokenKind getTokenID() const

If this is a source-language token (e.g.

void setIsPoisoned(bool Value=true)

setIsPoisoned - Mark this identifier as poisoned.

bool isPoisoned() const

Return true if this token has been poisoned.

bool isOutOfDate() const

Determine whether the information for this identifier is out of date with respect to the external sou...

void setIsFutureCompatKeyword(bool Val)

StringRef getName() const

Return the actual identifier string.

bool isFutureCompatKeyword() const

is/setIsFutureCompatKeyword - Initialize information about whether or not this language token is a ke...

bool isExtensionToken() const

get/setExtension - Initialize information about whether or not this language token is an extension.

void AddKeywords(const LangOptions &LangOpts)

Populate the identifier table with info about the language keywords for the language specified by Lan...

@ FEM_UnsetOnCommandLine

Used only for FE option processing; this is only used to indicate that the user did not specify an ex...

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

MacroArgs - An instance of this class captures information about the formal arguments specified to a ...

A description of the current definition of a macro.

MacroInfo * getMacroInfo()

SourceLocation getLocation() const

Encapsulates the data about a macro definition (e.g.

const_tokens_iterator tokens_begin() const

unsigned getNumTokens() const

Return the number of tokens that this macro expands to.

const Token & getReplacementToken(unsigned Tok) const

bool isObjectLike() const

Abstract interface for a module loader.

virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective)=0

Attempt to load the given module.

Represents a macro directive exported by a module.

Describes a module or submodule.

@ Hidden

All of the names in this module are hidden.

NumericLiteralParser - This performs strict semantic analysis of the content of a ppnumber,...

PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas, allowing hierarchical pragm...

A record of the steps taken while preprocessing a source file, including the various preprocessing di...

void setConditionalLevels(ArrayRef< PPConditionalInfo > CL)

void LexIncludeFilename(Token &FilenameTok)

Lex a token, producing a header-name token if possible.

bool markIncluded(FileEntryRef File)

Mark the file as included.

void FinalizeForModelFile()

Cleanup after model file parsing.

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...

bool creatingPCHWithThroughHeader()

True if creating a PCH with a through header.

void DumpToken(const Token &Tok, bool DumpFlags=false) const

Print the token to stderr, used for debugging.

void InitializeForModelFile()

Initialize the preprocessor to parse a model file.

void CollectPpImportSuffix(SmallVectorImpl< Token > &Toks)

Collect the tokens of a C++20 pp-import-suffix.

void setCodeCompletionTokenRange(const SourceLocation Start, const SourceLocation End)

Set the code completion token range for detecting replacement range later on.

bool LexAfterModuleImport(Token &Result)

Lex a token following the 'import' contextual keyword.

macro_iterator macro_begin(bool IncludeExternalMacros=true) const

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 ...

bool isSafeBufferOptOut(const SourceManager &SourceMgr, const SourceLocation &Loc) const

const char * getCheckPoint(FileID FID, const char *Start) const

Returns a pointer into the given file's buffer that's guaranteed to be between tokens.

IdentifierInfo * LookUpIdentifierInfo(Token &Identifier) const

Given a tok::raw_identifier token, look up the identifier information for the token and install it in...

void DumpMacro(const MacroInfo &MI) const

void setCodeCompletionReached()

Note that we hit the code-completion point.

bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line, unsigned Column)

Specify the point at which code-completion will be performed.

void makeModuleVisible(Module *M, SourceLocation Loc)

bool isInImportingCXXNamedModules() const

If we're importing a standard C++20 Named Modules.

void Lex(Token &Result)

Lex the next token for this preprocessor.

const TranslationUnitKind TUKind

The kind of translation unit we are processing.

bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)

Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...

void addCommentHandler(CommentHandler *Handler)

Add the specified comment handler to the preprocessor.

void removeCommentHandler(CommentHandler *Handler)

Remove the specified comment handler.

void HandlePoisonedIdentifier(Token &Identifier)

Display reason for poisoned identifier.

bool HandleIdentifier(Token &Identifier)

Callback invoked when the lexer reads an identifier and has filled in the tokens IdentifierInfo membe...

void addPPCallbacks(std::unique_ptr< PPCallbacks > C)

bool enterOrExitSafeBufferOptOutRegion(bool isEnter, const SourceLocation &Loc)

Alter the state of whether this PP currently is in a "-Wunsafe-buffer-usage" opt-out region.

void EnterMainSourceFile()

Enter the specified FileID as the main source file, which implicitly adds the builtin defines etc.

const MacroAnnotations & getMacroAnnotations(const IdentifierInfo *II) const

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

macro_iterator macro_end(bool IncludeExternalMacros=true) const

SourceManager & getSourceManager() const

bool isBacktrackEnabled() const

True if EnableBacktrackAtThisPos() was called and caching of tokens is on.

MacroDefinition getMacroDefinition(const IdentifierInfo *II)

void SetPoisonReason(IdentifierInfo *II, unsigned DiagID)

Specifies the reason for poisoning an identifier.

bool getCommentRetentionState() const

Module * getCurrentModuleImplementation()

Retrieves the module whose implementation we're current compiling, if any.

MacroMap::const_iterator macro_iterator

void createPreprocessingRecord()

Create a new preprocessing record, which will keep track of all macro expansions, macro definitions,...

SourceLocation SplitToken(SourceLocation TokLoc, unsigned Length)

Split the first Length characters out of the token starting at TokLoc and return a location pointing ...

Module * getCurrentModule()

Retrieves the module that we're currently building, if any.

bool isPPInSafeBufferOptOutRegion()

void setCurrentFPEvalMethod(SourceLocation PragmaLoc, LangOptions::FPEvalMethodKind Val)

const TargetInfo & getTargetInfo() const

bool LexHeaderName(Token &Result, bool AllowMacroExpansion=true)

Lex a token, forming a header-name token if possible.

bool isPCHThroughHeader(const FileEntry *FE)

Returns true if the FileEntry is the PCH through header.

void DumpLocation(SourceLocation Loc) const

bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value)

Parses a simple integer literal to get its numeric value.

void LexUnexpandedToken(Token &Result)

Just like Lex, but disables macro expansion of identifier tokens.

bool creatingPCHWithPragmaHdrStop()

True if creating a PCH with a #pragma hdrstop.

void Initialize(const TargetInfo &Target, const TargetInfo *AuxTarget=nullptr)

Initialize the preprocessor using information about the target.

FileID getPredefinesFileID() const

Returns the FileID for the preprocessor predefines.

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 HandleComment(Token &result, SourceRange Comment)

HeaderSearch & getHeaderSearchInfo() const

bool setDeserializedSafeBufferOptOutMap(const SmallVectorImpl< SourceLocation > &SrcLocSeqs)

ExternalPreprocessorSource * getExternalSource() const

SmallVector< SourceLocation, 64 > serializeSafeBufferOptOutMap() const

void recomputeCurLexerKind()

Recompute the current lexer kind based on the CurLexer/ CurTokenLexer pointers.

Preprocessor(std::shared_ptr< PreprocessorOptions > PPOpts, DiagnosticsEngine &diags, const LangOptions &LangOpts, SourceManager &SM, HeaderSearch &Headers, ModuleLoader &TheModuleLoader, IdentifierInfoLookup *IILookup=nullptr, bool OwnsHeaderSearch=false, TranslationUnitKind TUKind=TU_Complete)

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.

IdentifierTable & getIdentifierTable()

const LangOptions & getLangOpts() const

void setTUFPEvalMethod(LangOptions::FPEvalMethodKind Val)

void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled)

Hook used by the lexer to invoke the "included file" code completion point.

llvm::DenseMap< FileID, SafeBufferOptOutRegionsTy > LoadedRegions

void PoisonSEHIdentifiers(bool Poison=true)

size_t getTotalMemory() const

void LexTokensUntilEOF(std::vector< Token > *Tokens=nullptr)

Lex all tokens for this preprocessor until (and excluding) end of file.

bool usingPCHWithPragmaHdrStop()

True if using a PCH with a #pragma hdrstop.

void CodeCompleteNaturalLanguage()

Hook used by the lexer to invoke the "natural language" code completion point.

void EndSourceFile()

Inform the preprocessor callbacks that processing is complete.

DiagnosticsEngine & getDiagnostics() const

StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const

Return the name of the macro defined before Loc that has spelling Tokens.

void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter)

Set the code completion token for filtering purposes.

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

void SkipTokensWhileUsingPCH()

Skip tokens until after the #include of the through header or until after a #pragma hdrstop.

bool usingPCHWithThroughHeader()

True if using a PCH with a through header.

ScratchBuffer - This class exposes a simple interface for the dynamic construction of tokens.

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

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

bool isLocalSourceLocation(SourceLocation Loc) const

Returns true if Loc did not come from a PCH/Module.

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)

Create a new FileID that represents the specified file being #included from the specified IncludePosi...

FileID getMainFileID() const

Returns the FileID of the main source file.

const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const

Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.

void overrideFileContents(FileEntryRef SourceFile, const llvm::MemoryBufferRef &Buffer)

Override the contents of the given source file by providing an already-allocated buffer.

bool isLoadedFileID(FileID FID) const

Returns true if FID came from a PCH/Module.

const FileEntry * getFileEntryForID(FileID FID) const

Returns the FileEntry record for the provided FileID.

SourceLocation createExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned Length, bool ExpansionIsTokenRange=true, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)

Creates an expansion SLocEntry for a macro use.

bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const

Determines the order of 2 source locations in the translation unit.

std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)

Retrieve the memory buffer associated with the given file.

A trivial tuple used to represent a source range.

StringLiteralParser - This decodes string escape characters and performs wide string analysis and Tra...

Exposes information about the current target.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

void setLiteralData(const char *Ptr)

bool hasUCN() const

Returns true if this token contains a universal character name.

bool isLiteral() const

Return true if this is a "literal", like a numeric constant, string, etc.

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

unsigned getLength() const

void setLength(unsigned Len)

bool isExpandDisabled() const

Return true if this identifier token should never be expanded in the future, due to C99 6....

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 hasLeadingSpace() const

Return true if this token has whitespace before it.

void setLocation(SourceLocation L)

bool hasLeadingEmptyMacro() const

Return true if this token has an empty macro before it.

void setRawIdentifierData(const char *Ptr)

bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const

bool isNot(tok::TokenKind K) const

bool isAnnotation() const

Return true if this is any of tok::annot_* kind tokens.

void startToken()

Reset all flags to cleared.

bool needsCleaning() const

Return true if this token has trigraphs or escaped newlines in it.

void setIdentifierInfo(IdentifierInfo *II)

void setFlagValue(TokenFlags Flag, bool Val)

Set a flag to either true or false.

Defines the clang::TargetInfo interface.

const char * getTokenName(TokenKind Kind) LLVM_READNONE

Determines the name of a token as used within the front end.

The JSON file list parser is used to communicate input to InstallAPI.

void expandUCNs(SmallVectorImpl< char > &Buf, StringRef Input)

Copy characters from Input to Buf, expanding any UCNs.

llvm::Registry< PragmaHandler > PragmaHandlerRegistry

Registry of pragma handlers added by plugins.

@ Result

The result type of a method or function.

TranslationUnitKind

Describes the kind of translation unit being processed.

@ TU_Prefix

The translation unit is a prefix to a translation unit, and is not complete.