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

1

2

3

4

5

6

7

8

9

10

11

12

13

21#include "llvm/ADT/StringSwitch.h"

22#include "llvm/Support/MemoryBufferRef.h"

23#include "llvm/Support/Path.h"

24#include

25

26using namespace clang;

27

28

29

30

31

32

33

35 if (IsFileLexer())

36 return IncludeMacroStack.empty();

37

38

39 assert(IsFileLexer(IncludeMacroStack[0]) &&

40 "Top level include stack isn't our primary lexer?");

41 return llvm::none_of(

42 llvm::drop_begin(IncludeMacroStack),

43 [&](const IncludeStackInfo &ISI) -> bool { return IsFileLexer(ISI); });

44}

45

46

47

48

50 if (IsFileLexer())

51 return CurPPLexer;

52

53

54 for (const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {

55 if (IsFileLexer(ISI))

56 return ISI.ThePPLexer;

57 }

58 return nullptr;

59}

60

61

62

63

64

65

66

67

70 bool IsFirstIncludeOfFile) {

71 assert(!CurTokenLexer && "Cannot #include a file inside a macro!");

72 ++NumEnteredSourceFiles;

73

74 if (MaxIncludeStackDepth < IncludeMacroStack.size())

75 MaxIncludeStackDepth = IncludeMacroStack.size();

76

77

78 std::optionalllvm::MemoryBufferRef InputFile =

80 if (!InputFile) {

82 Diag(Loc, diag::err_pp_error_opening_file)

83 << std::string(SourceMgr.getBufferName(FileStart)) << "";

84 return true;

85 }

86

90 CodeCompletionLoc =

92 }

93

94 Lexer *TheLexer = new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile);

96 FID != PredefinesFileID) {

99 DepDirectives =

101 TheLexer->DepDirectives = *DepDirectives;

102 }

103 }

104 }

105

106 EnterSourceFileWithLexer(TheLexer, CurDir);

107 return false;

108}

109

110

111

112void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer,

115

116

117 if (CurPPLexer || CurTokenLexer)

118 PushIncludeMacroStack();

119

120 CurLexer.reset(TheLexer);

121 CurPPLexer = TheLexer;

122 CurDirLookup = CurDir;

123 CurLexerSubmodule = nullptr;

124 if (CurLexerCallback != CLK_LexAfterModuleImport)

125 CurLexerCallback = TheLexer->isDependencyDirectivesLexer()

126 ? CLK_DependencyDirectivesLexer

127 : CLK_Lexer;

128

129

130 if (Callbacks && !CurLexer->Is_PragmaLexer) {

133

136 if (PrevPPLexer) {

137 PrevFID = PrevPPLexer->getFileID();

139 }

142 Callbacks->LexedFileChanged(CurLexer->getFileID(),

144 FileType, PrevFID, EnterLoc);

145 }

146}

147

148

149

152 std::unique_ptr TokLexer;

153 if (NumCachedTokenLexers == 0) {

154 TokLexer = std::make_unique(Tok, ILEnd, Macro, Args, *this);

155 } else {

156 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);

157 TokLexer->Init(Tok, ILEnd, Macro, Args);

158 }

159

160 PushIncludeMacroStack();

161 CurDirLookup = nullptr;

162 CurTokenLexer = std::move(TokLexer);

163 if (CurLexerCallback != CLK_LexAfterModuleImport)

164 CurLexerCallback = CLK_TokenLexer;

165}

166

167

168

169

170

171

172

173

174

175

176

177

178

179void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks,

180 bool DisableMacroExpansion, bool OwnsTokens,

181 bool IsReinject) {

182 if (CurLexerCallback == CLK_CachingLexer) {

184 assert(IsReinject && "new tokens in the middle of cached stream");

185

186

188 Toks, Toks + NumToks);

189 if (OwnsTokens)

190 delete [] Toks;

191 return;

192 }

193

194

195

196 ExitCachingLexMode();

197 EnterTokenStream(Toks, NumToks, DisableMacroExpansion, OwnsTokens,

198 IsReinject);

199 EnterCachingLexMode();

200 return;

201 }

202

203

204 std::unique_ptr TokLexer;

205 if (NumCachedTokenLexers == 0) {

206 TokLexer = std::make_unique(

207 Toks, NumToks, DisableMacroExpansion, OwnsTokens, IsReinject, *this);

208 } else {

209 TokLexer = std::move(TokenLexerCache[--NumCachedTokenLexers]);

210 TokLexer->Init(Toks, NumToks, DisableMacroExpansion, OwnsTokens,

211 IsReinject);

212 }

213

214

215 PushIncludeMacroStack();

216 CurDirLookup = nullptr;

217 CurTokenLexer = std::move(TokLexer);

218 if (CurLexerCallback != CLK_LexAfterModuleImport)

219 CurLexerCallback = CLK_TokenLexer;

220}

221

222

223

227

228 StringRef FilePath = File.getDir().getName();

229 StringRef Path = FilePath;

230 while (Path.empty()) {

232 if (*CurDir == Dir) {

233 Result = FilePath.substr(Path.size());

234 llvm::sys::path::append(Result,

235 llvm::sys::path::filename(File.getName()));

236 return;

237 }

238 }

239

240 Path = llvm::sys::path::parent_path(Path);

241 }

242

244}

245

246void Preprocessor::PropagateLineStartLeadingSpaceInfo(Token &Result) {

247 if (CurTokenLexer) {

248 CurTokenLexer->PropagateLineStartLeadingSpaceInfo(Result);

249 return;

250 }

251 if (CurLexer) {

252 CurLexer->PropagateLineStartLeadingSpaceInfo(Result);

253 return;

254 }

255

256

257}

258

259

260

261

262

263

264

265const char *Preprocessor::getCurLexerEndPos() {

266 const char *EndPos = CurLexer->BufferEnd;

267 if (EndPos != CurLexer->BufferStart &&

268 (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {

269 --EndPos;

270

271

272 if (EndPos != CurLexer->BufferStart &&

273 (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&

274 EndPos[-1] != EndPos[0])

275 --EndPos;

276 }

277

278 return EndPos;

279}

280

284 SubMods.push_back(&Mod);

287}

288

289void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) {

290 std::optionalModule::Header UmbrellaHeader =

292 assert(UmbrellaHeader && "Module must use umbrella header");

295 if (getDiagnostics().isIgnored(diag::warn_uncovered_module_header,

296 ExpectedHeadersLoc))

297 return;

298

302 std::error_code EC;

303 for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC),

304 End;

305 Entry != End && !EC; Entry.increment(EC)) {

306 using llvm::StringSwitch;

307

308

309

310 if (!StringSwitch(llvm::sys::path::extension(Entry->path()))

311 .Cases(".h", ".H", ".hh", ".hpp", true)

312 .Default(false))

313 continue;

314

315 if (auto Header = getFileManager().getOptionalFileRef(Entry->path()))

318

321 Diag(ExpectedHeadersLoc, diag::warn_uncovered_module_header)

323 }

324 }

325 }

326}

327

328

329

330

332 assert(!CurTokenLexer &&

333 "Ending a file when currently in a macro!");

334

336

337 if (IncludeMacroStack.empty() &&

339

340

341 Diag(UnclosedSafeBufferOptOutLoc,

342 diag::err_pp_unclosed_pragma_unsafe_buffer_usage);

343 }

344

345

346 const bool LeavingSubmodule = CurLexer && CurLexerSubmodule;

347 if ((LeavingSubmodule || IncludeMacroStack.empty()) &&

348 !BuildingSubmoduleStack.empty() &&

349 BuildingSubmoduleStack.back().IsPragma) {

350 Diag(BuildingSubmoduleStack.back().ImportLoc,

351 diag::err_pp_module_begin_without_module_end);

353

355 const char *EndPos = getCurLexerEndPos();

356 CurLexer->BufferPtr = EndPos;

357 CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);

358 Result.setAnnotationEndLoc(Result.getLocation());

359 Result.setAnnotationValue(M);

360 return true;

361 }

362

363

364 if (CurPPLexer) {

367

371 MI->setUsedForHeaderGuard(true);

375 DefinedMacro != ControllingMacro &&

376 CurLexer->isFirstTimeLexingFile()) {

377

378

379

380

381

382

383

384 const StringRef ControllingMacroName = ControllingMacro->getName();

385 const StringRef DefinedMacroName = DefinedMacro->getName();

386 const size_t MaxHalfLength = std::max(ControllingMacroName.size(),

387 DefinedMacroName.size()) / 2;

388 const unsigned ED = ControllingMacroName.edit_distance(

389 DefinedMacroName, true, MaxHalfLength);

390 if (ED <= MaxHalfLength) {

391

393 diag::warn_header_guard)

396 diag::note_header_guard)

398 << ControllingMacro

401 ControllingMacro->getName());

402 }

403 }

404 }

405 }

406 }

407 }

408

409

410

411

412 if (PragmaARCCFCodeAuditedInfo.second.isValid() && !isEndOfMacro &&

413 !(CurLexer && CurLexer->Is_PragmaLexer)) {

414 Diag(PragmaARCCFCodeAuditedInfo.second,

415 diag::err_pp_eof_in_arc_cf_code_audited);

416

417

418 PragmaARCCFCodeAuditedInfo = {nullptr, SourceLocation()};

419 }

420

421

422

423

424 if (PragmaAssumeNonNullLoc.isValid() &&

425 !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {

426

427

428

430 PreambleRecordedPragmaAssumeNonNullLoc = PragmaAssumeNonNullLoc;

431 else

432 Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull);

433

435 }

436

437 bool LeavingPCHThroughHeader = false;

438

439

440

441 if (!IncludeMacroStack.empty()) {

442

443

446 CodeCompletionFileLoc) {

447 assert(CurLexer && "Got EOF but no current lexer set!");

449 CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);

450 CurLexer.reset();

451

452 CurPPLexer = nullptr;

454 return true;

455 }

456

457 if (!isEndOfMacro && CurPPLexer &&

459

460 (PredefinesFileID.isValid() &&

461 CurPPLexer->getFileID() == PredefinesFileID))) {

462

463

464 unsigned NumFIDs =

468 }

469

470 bool ExitedFromPredefinesFile = false;

472 if (!isEndOfMacro && CurPPLexer) {

473 ExitedFID = CurPPLexer->getFileID();

474

475 assert(PredefinesFileID.isValid() &&

476 "HandleEndOfFile is called before PredefinesFileId is set");

477 ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);

478 }

479

480 if (LeavingSubmodule) {

481

483

484

485 const char *EndPos = getCurLexerEndPos();

487 CurLexer->BufferPtr = EndPos;

488 CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);

489 Result.setAnnotationEndLoc(Result.getLocation());

490 Result.setAnnotationValue(M);

491 }

492

493 bool FoundPCHThroughHeader = false;

497 FoundPCHThroughHeader = true;

498

499

501

502

503 PropagateLineStartLeadingSpaceInfo(Result);

504

505

506 if (Callbacks && !isEndOfMacro && CurPPLexer) {

511 Callbacks->LexedFileChanged(CurPPLexer->getFileID(),

514 }

515

516

517

518

519 if (ExitedFromPredefinesFile) {

520 replayPreambleConditionalStack();

521 if (PreambleRecordedPragmaAssumeNonNullLoc.isValid())

522 PragmaAssumeNonNullLoc = PreambleRecordedPragmaAssumeNonNullLoc;

523 }

524

525 if (!isEndOfMacro && CurPPLexer && FoundPCHThroughHeader &&

528

529

530 LeavingPCHThroughHeader = true;

531 } else {

532

533 return LeavingSubmodule;

534 }

535 }

536

537 assert(CurLexer && "Got EOF but no current lexer set!");

538 const char *EndPos = getCurLexerEndPos();

540 CurLexer->BufferPtr = EndPos;

541

542 if (getLangOpts().IncrementalExtensions) {

543 CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_repl_input_end);

544 Result.setAnnotationEndLoc(Result.getLocation());

545 Result.setAnnotationValue(nullptr);

546 } else {

547 CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);

548 }

549

551

552

553

554

555

556

557 if (CurLexer->getFileLoc() == CodeCompletionFileLoc)

558 Result.setLocation(Result.getLocation().getLocWithOffset(-1));

559 }

560

562

563 Diag(CurLexer->getFileLoc(), diag::err_pp_through_header_not_seen)

564 << PPOpts->PCHThroughHeader << 0;

565 }

566

568

569 CurLexer.reset();

570

572 CurPPLexer = nullptr;

573

575

576

577

578 for (WarnUnusedMacroLocsTy::iterator

579 I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end();

580 I!=E; ++I)

581 Diag(*I, diag::pp_macro_not_used);

582 }

583

584

585

586

587

591 for (auto *M : AllMods)

592 diagnoseMissingHeaderInUmbrellaDir(*M);

593 }

594

595 return true;

596}

597

598

599

601 assert(CurTokenLexer && !CurPPLexer &&

602 "Ending a macro when currently in a #include file!");

603

604 if (!MacroExpandingLexersStack.empty() &&

605 MacroExpandingLexersStack.back().first == CurTokenLexer.get())

606 removeCachedMacroExpandedTokensOfLastLexer();

607

608

609 if (NumCachedTokenLexers == TokenLexerCacheSize)

610 CurTokenLexer.reset();

611 else

612 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);

613

614

616}

617

618

619

620

622 assert(!IncludeMacroStack.empty() && "Ran out of stack entries to load");

623

624 if (CurTokenLexer) {

625

626 if (NumCachedTokenLexers == TokenLexerCacheSize)

627 CurTokenLexer.reset();

628 else

629 TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer);

630 }

631

632 PopIncludeMacroStack();

633}

634

635

636

637

639 assert(CurTokenLexer && !CurPPLexer &&

640 "Pasted comment can only be formed from macro");

641

642

643

645 bool LexerWasInPPMode = false;

646 for (const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {

647 if (ISI.ThePPLexer == nullptr) continue;

648

649

650

651

652

653

654

655 FoundLexer = ISI.ThePPLexer;

659 break;

660 }

661

662

663

664

666

667

668

669

670

671

672

673 while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof))

674 Lex(Tok);

675

676

677 if (Tok.is(tok::eod)) {

678 assert(FoundLexer && "Can't get end of line without an active lexer");

679

681

682

683

684 if (LexerWasInPPMode) return;

685

686

688 return Lex(Tok);

689 }

690

691

692

693

694

695 assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");

696}

697

699 bool ForPragma) {

700 if (getLangOpts().ModulesLocalVisibility) {

701

702 BuildingSubmoduleStack.push_back(

703 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,

704 PendingModuleMacroNames.size()));

705 if (Callbacks)

706 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);

707 return;

708 }

709

710

711

712

713

716 ModMap.resolveUses(M, false);

718

719

720 auto R = Submodules.insert(std::make_pair(M, SubmoduleState()));

721 auto &State = R.first->second;

722 bool FirstTime = R.second;

723 if (FirstTime) {

724

725

726

727

728

729

730 auto &StartingMacros = NullSubmoduleState.Macros;

731

732

733

734 for (auto &Macro : StartingMacros) {

735

736 if (!Macro.second.getLatest() &&

737 Macro.second.getOverriddenMacros().empty())

738 continue;

739

740 MacroState MS(Macro.second.getLatest());

741 MS.setOverriddenMacros(*this, Macro.second.getOverriddenMacros());

742 State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));

743 }

744 }

745

746

747 BuildingSubmoduleStack.push_back(

748 BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,

749 PendingModuleMacroNames.size()));

750

751 if (Callbacks)

752 Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);

753

754

755 CurSubmoduleState = &State;

756

757

758 if (FirstTime)

760}

761

762bool Preprocessor::needModuleMacros() const {

763

764 if (BuildingSubmoduleStack.empty())

765 return false;

766

767

768 if (getLangOpts().ModulesLocalVisibility)

769 return true;

770

771

773}

774

776 if (BuildingSubmoduleStack.empty() ||

777 BuildingSubmoduleStack.back().IsPragma != ForPragma) {

778 assert(ForPragma && "non-pragma module enter/leave mismatch");

779 return nullptr;

780 }

781

782 auto &Info = BuildingSubmoduleStack.back();

783

784 Module *LeavingMod = Info.M;

786

787 if (!needModuleMacros() ||

788 (getLangOpts().ModulesLocalVisibility &&

790

791

792

793 BuildingSubmoduleStack.pop_back();

794

795 if (Callbacks)

796 Callbacks->LeftSubmodule(LeavingMod, ImportLoc, ForPragma);

797

799 return LeavingMod;

800 }

801

802

804 for (unsigned I = Info.OuterPendingModuleMacroNames;

805 I != PendingModuleMacroNames.size(); ++I) {

806 auto *II = PendingModuleMacroNames[I];

807 if (!VisitedMacros.insert(II).second)

808 continue;

809

810 auto MacroIt = CurSubmoduleState->Macros.find(II);

811 if (MacroIt == CurSubmoduleState->Macros.end())

812 continue;

813 auto &Macro = MacroIt->second;

814

815

817 auto *OldState = Info.OuterSubmoduleState;

818 if (getLangOpts().ModulesLocalVisibility)

819 OldState = &NullSubmoduleState;

820 if (OldState && OldState != CurSubmoduleState) {

821

822

823 auto &OldMacros = OldState->Macros;

824 auto OldMacroIt = OldMacros.find(II);

825 if (OldMacroIt == OldMacros.end())

826 OldMD = nullptr;

827 else

828 OldMD = OldMacroIt->second.getLatest();

829 }

830

831

832

833 bool ExplicitlyPublic = false;

834 for (auto *MD = Macro.getLatest(); MD != OldMD; MD = MD->getPrevious()) {

835 assert(MD && "broken macro directive chain");

836

837 if (auto *VisMD = dyn_cast(MD)) {

838

839

840 if (VisMD->isPublic())

841 ExplicitlyPublic = true;

842 else if (!ExplicitlyPublic)

843

844 break;

845 } else {

848 Def = DefMD->getInfo();

849

850

851

852 bool IsNew;

853

854

855 if (Def || !Macro.getOverriddenMacros().empty())

856 addModuleMacro(LeavingMod, II, Def, Macro.getOverriddenMacros(),

857 IsNew);

858

859 if (getLangOpts().ModulesLocalVisibility) {

860

861

862 Macro.setLatest(nullptr);

863 Macro.setOverriddenMacros(*this, {});

864 }

865 break;

866 }

867 }

868 }

869 PendingModuleMacroNames.resize(Info.OuterPendingModuleMacroNames);

870

871

872

873

874

875

876

877 if (getLangOpts().ModulesLocalVisibility)

878 CurSubmoduleState = Info.OuterSubmoduleState;

879

880 BuildingSubmoduleStack.pop_back();

881

882 if (Callbacks)

883 Callbacks->LeftSubmodule(LeavingMod, ImportLoc, ForPragma);

884

885

887 return LeavingMod;

888}

Defines the clang::FileManager interface and associated types.

llvm::MachO::FileType FileType

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

static void collectAllSubModulesWithUmbrellaHeader(const Module &Mod, SmallVectorImpl< const Module * > &SubMods)

static void computeRelativePath(FileManager &FM, const DirectoryEntry *Dir, FileEntryRef File, SmallString< 128 > &Result)

Compute the relative path that names the given file relative to the given directory.

Defines the clang::Preprocessor interface.

Defines the SourceManager interface.

A directive for a defined macro or a macro imported from a module.

StringRef getName() const

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

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

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

Implements support for file system lookup, file system caching, and directory search management.

llvm::vfs::FileSystem & getVirtualFileSystem() const

OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName, bool CacheFailure=true)

Get a DirectoryEntryRef if it exists, without doing anything on error.

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

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

bool isCompilingModule() const

Are we compiling a module?

Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.

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

Encapsulates changes to the "macros namespace" (the location where the macro name became active,...

const MacroDirective * getPrevious() const

Get previous definition of the macro with the same name.

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

bool resolveExports(Module *Mod, bool Complain)

Resolve all of the unresolved exports in the given module.

bool resolveConflicts(Module *Mod, bool Complain)

Resolve all of the unresolved conflicts in the given module.

bool isHeaderInUnavailableModule(FileEntryRef Header) const

Determine whether the given header is part of a module marked 'unavailable'.

bool resolveUses(Module *Mod, bool Complain)

Resolve all of the unresolved uses in the given module.

Describes a module or submodule.

StringRef getTopLevelModuleName() const

Retrieve the name of the top-level module.

llvm::iterator_range< submodule_iterator > submodules()

std::optional< Header > getUmbrellaHeaderAsWritten() const

Retrieve the umbrella header as written.

std::string getFullModuleName(bool AllowStringLiterals=false) const

Retrieve the full name of this module, including the path from its top-level module.

OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const

Get the effective umbrella directory for this module: either the one explicitly written in the module...

const IdentifierInfo * GetDefinedMacro() const

If the ControllingMacro is followed by a macro definition, return the macro that was defined.

const IdentifierInfo * GetControllingMacroAtEndOfFile() const

Once the entire file has been lexed, if there is a controlling macro, return it.

SourceLocation GetDefinedLocation() const

SourceLocation GetMacroLocation() const

unsigned getInitialNumSLocEntries() const

Number of SLocEntries before lexing the file.

bool LexingRawMode

True if in raw mode.

bool ParsingPreprocessorDirective

True when parsing #XXX; turns '\n' into a tok::eod token.

MultipleIncludeOpt MIOpt

A state machine that detects the #ifndef-wrapping a file idiom for the multiple-include optimization.

OptionalFileEntryRef getFileEntry() const

getFileEntry - Return the FileEntry corresponding to this FileID.

virtual SourceLocation getSourceLocation()=0

Return the source location for the next observable location.

bool creatingPCHWithThroughHeader()

True if creating a PCH with a through header.

ModuleMacro * addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides, bool &IsNew)

Register an exported macro for a module and identifier.

bool isIncrementalProcessingEnabled() const

Returns true if incremental processing is enabled.

const MacroInfo * getMacroInfo(const IdentifierInfo *II) const

bool isRecordingPreamble() const

bool isInPrimaryFile() const

Return true if we're in the top-level file, not in a #include.

void EnterSubmodule(Module *M, SourceLocation ImportLoc, bool ForPragma)

bool HandleEndOfTokenLexer(Token &Result)

Callback invoked when the current TokenLexer hits the end of its token stream.

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.

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

SourceManager & getSourceManager() const

bool isMacroDefined(StringRef Id)

Module * getCurrentModule()

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

bool isPPInSafeBufferOptOutRegion()

FileManager & getFileManager() const

PreprocessorOptions & getPreprocessorOpts() const

Retrieve the preprocessor options used to initialize this preprocessor.

bool isPCHThroughHeader(const FileEntry *FE)

Returns true if the FileEntry is the PCH through header.

FileID getPredefinesFileID() const

Returns the FileID for the preprocessor predefines.

bool isCodeCompletionEnabled() const

Determine if we are performing code completion.

PreprocessorLexer * getCurrentFileLexer() const

Return the current file lexer being lexed from.

HeaderSearch & getHeaderSearchInfo() const

Module * LeaveSubmodule(bool ForPragma)

void recomputeCurLexerKind()

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

const LangOptions & getLangOpts() const

void RemoveTopOfLexerStack()

Pop the current lexer/macro exp off the top of the lexer stack.

bool HandleEndOfFile(Token &Result, bool isEndOfMacro=false)

Callback invoked when the lexer hits the end of the current file.

DiagnosticsEngine & getDiagnostics() const

void EnterMacro(Token &Tok, SourceLocation ILEnd, MacroInfo *Macro, MacroArgs *Args)

Add a Macro to the top of the include stack and start lexing tokens from it instead of the current bu...

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

void HandleMicrosoftCommentPaste(Token &Tok)

When the macro expander pastes together a comment (/##/) in Microsoft mode, this method handles updat...

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

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

OptionalFileEntryRef getFileEntryRefForID(FileID FID) const

Returns the FileEntryRef for the provided FileID.

StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const

Return the filename or buffer identifier of the buffer the location is in.

FileID translateFile(const FileEntry *SourceFile) const

Get the FileID for the given file.

unsigned local_sloc_entry_size() const

Get the number of local SLocEntries we have.

SourceLocation getLocForEndOfFile(FileID FID) const

Return the source location corresponding to the last byte of the specified file.

SourceLocation getIncludeLoc(FileID FID) const

Returns the include location if FID is a #include'd file otherwise it returns an invalid location.

void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs, bool Force=false)

Set the number of FileIDs (files and macros) that were created during preprocessing of FID,...

const FileEntry * getFileEntryForID(FileID FID) const

Returns the FileEntry record for the provided FileID.

SourceLocation getLocForStartOfFile(FileID FID) const

Return the source location corresponding to the first byte of the specified file.

SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const

Return the file characteristic of the specified source location, indicating whether this is a normal ...

std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const

Return the buffer for the specified FileID.

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

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

bool isNot(tok::TokenKind K) const

CharacteristicKind

Indicates whether a file or directory holds normal user code, system code, or system code which is im...

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

@ Result

The result type of a method or function.

@ TU_Complete

The translation unit is a complete translation unit.