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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

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

41#include "llvm/ADT/ScopeExit.h"

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

43#include "llvm/ADT/StringExtras.h"

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

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

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

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

48#include "llvm/Support/SaveAndRestore.h"

49#include

50#include

51#include

52#include

53#include

54#include

55

56using namespace clang;

57

58

59

60

61

63 static_assert(std::is_trivially_destructible_v, "");

65}

66

70}

71

73Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {

75}

76

78Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,

79 bool isPublic) {

80 return new (BP) VisibilityMacroDirective(Loc, isPublic);

81}

82

83

84

87

90 while (Tmp.isNot(tok::eod)) {

91 assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");

93 }

95 return Res;

96}

97

98

105

106

107

113

115

116

117

118

119

120 static constexpr StringRef ReservedMacro[] = {

121 "_ATFILE_SOURCE",

122 "_BSD_SOURCE",

123 "_CRT_NONSTDC_NO_WARNINGS",

124 "_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES",

125 "_CRT_SECURE_NO_WARNINGS",

126 "_FILE_OFFSET_BITS",

127 "_FORTIFY_SOURCE",

128 "_GLIBCXX_ASSERTIONS",

129 "_GLIBCXX_CONCEPT_CHECKS",

130 "_GLIBCXX_DEBUG",

131 "_GLIBCXX_DEBUG_PEDANTIC",

132 "_GLIBCXX_PARALLEL",

133 "_GLIBCXX_PARALLEL_ASSERTIONS",

134 "_GLIBCXX_SANITIZE_VECTOR",

135 "_GLIBCXX_USE_CXX11_ABI",

136 "_GLIBCXX_USE_DEPRECATED",

137 "_GNU_SOURCE",

138 "_ISOC11_SOURCE",

139 "_ISOC95_SOURCE",

140 "_ISOC99_SOURCE",

141 "_LARGEFILE64_SOURCE",

142 "_POSIX_C_SOURCE",

143 "_REENTRANT",

144 "_SVID_SOURCE",

145 "_THREAD_SAFE",

146 "_XOPEN_SOURCE",

147 "_XOPEN_SOURCE_EXTENDED",

148 "__STDCPP_WANT_MATH_SPEC_FUNCS__",

149 "__STDC_FORMAT_MACROS",

150 };

151 return llvm::binary_search(ReservedMacro, MacroName);

152}

153

156 const StringRef MacroName) {

157

158

160 return true;

161

162 if (!SourceMgr.isWrittenInBuiltinFile(MI->getDefinitionLoc()))

163 return false;

164

165

166 if (MacroName.starts_with("__STDC"))

167 return true;

168

169 if (MacroName == "__cplusplus")

170 return true;

171

172 if (MacroName.starts_with("__cpp"))

173 return true;

174

175 return false;

176}

177

180 if (Lang.CPlusPlus &&

182 PP.getTargetInfo(), Lang, false) > 0) {

187

190 }

191 return false;

192}

193

201 if (Lang.CPlusPlus11 && (Text == "override" || Text == "final"))

206}

207

217

218

219

220

221

222

224

225

226 if (::llvm::sys::path::begin(Include)->equals_insensitive("boost"))

227 return true;

228

229

230

231 static const size_t MaxStdHeaderNameLen = 18u;

232 if (Include.size() > MaxStdHeaderNameLen)

233 return false;

234

235

237 for (char &Ch : LowerInclude) {

238

239 if (static_cast<unsigned char>(Ch) > 0x7f)

240 return false;

241

242 if (Ch >= 'A' && Ch <= 'Z')

243 Ch += 'a' - 'A';

244

245 else if (::llvm::sys::path::is_separator(Ch))

246 Ch = '/';

247 }

248

249

250 return llvm::StringSwitch(LowerInclude)

251

252 .Cases({"assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h"}, true)

253 .Cases({"float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h"},

254 true)

255 .Cases({"math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h"}, true)

256 .Cases({"stdatomic.h", "stdbool.h", "stdckdint.h", "stdcountof.h"}, true)

257 .Cases({"stddef.h", "stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h"},

258 true)

259 .Cases({"string.h", "tgmath.h", "threads.h", "time.h", "uchar.h"}, true)

260 .Cases({"wchar.h", "wctype.h"}, true)

261

262

263 .Cases({"cassert", "ccomplex", "cctype", "cerrno", "cfenv"}, true)

264 .Cases({"cfloat", "cinttypes", "ciso646", "climits", "clocale"}, true)

265 .Cases({"cmath", "csetjmp", "csignal", "cstdalign", "cstdarg"}, true)

266 .Cases({"cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib"}, true)

267 .Cases({"cstring", "ctgmath", "ctime", "cuchar", "cwchar"}, true)

268 .Case("cwctype", true)

269

270

271 .Cases({"algorithm", "fstream", "list", "regex", "thread"}, true)

272 .Cases({"array", "functional", "locale", "scoped_allocator", "tuple"},

273 true)

274 .Cases({"atomic", "future", "map", "set", "type_traits"}, true)

275 .Cases(

276 {"bitset", "initializer_list", "memory", "shared_mutex", "typeindex"},

277 true)

278 .Cases({"chrono", "iomanip", "mutex", "sstream", "typeinfo"}, true)

279 .Cases({"codecvt", "ios", "new", "stack", "unordered_map"}, true)

280 .Cases({"complex", "iosfwd", "numeric", "stdexcept", "unordered_set"},

281 true)

282 .Cases(

283 {"condition_variable", "iostream", "ostream", "streambuf", "utility"},

284 true)

285 .Cases({"deque", "istream", "queue", "string", "valarray"}, true)

286 .Cases({"exception", "iterator", "random", "strstream", "vector"}, true)

287 .Cases({"forward_list", "limits", "ratio", "system_error"}, true)

288

289

290 .Cases({"aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h"}, true)

291 .Cases({"fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h"}, true)

292 .Cases({"grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h"}, true)

293 .Cases({"mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h"},

294 true)

295 .Cases({"netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h"},

296 true)

297 .Cases({"regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h"}, true)

298 .Cases({"strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h"},

299 true)

300 .Cases({"sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h",

301 "sys/socket.h"},

302 true)

303 .Cases({"sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h",

304 "sys/types.h"},

305 true)

306 .Cases(

307 {"sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h"},

308 true)

309 .Cases({"tar.h", "termios.h", "trace.h", "ulimit.h"}, true)

310 .Cases({"unistd.h", "utime.h", "utmpx.h", "wordexp.h"}, true)

312}

313

314

315

316

317

318

319

320

321

322static std::optional

323findSimilarStr(StringRef LHS, const std::vector &Candidates) {

324

325

326 for (StringRef C : Candidates) {

327 if (LHS.equals_insensitive(C)) {

328 return C;

329 }

330 }

331

332

333

334

335 size_t Length = LHS.size();

336 size_t MaxDist = Length < 3 ? Length - 1 : Length / 3;

337

338 std::optional<std::pair<StringRef, size_t>> SimilarStr;

339 for (StringRef C : Candidates) {

340 size_t CurDist = LHS.edit_distance(C, true);

341 if (CurDist <= MaxDist) {

342 if (!SimilarStr) {

343

344 SimilarStr = {C, CurDist};

345 } else if (CurDist < SimilarStr->second) {

346

347 SimilarStr = {C, CurDist};

348 }

349 }

350 }

351

352 if (SimilarStr) {

353 return SimilarStr->first;

354 } else {

355 return std::nullopt;

356 }

357}

358

360 bool *ShadowFlag) {

361

362 if (MacroNameTok.is(tok::eod))

363 return Diag(MacroNameTok, diag::err_pp_missing_macro_name);

364

366 if (!II)

367 return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);

368

370

371

373 ? diag::ext_pp_operator_used_as_macro_name

374 : diag::err_pp_operator_used_as_macro_name)

375 << II << MacroNameTok.getKind();

376

377

378 }

379

381

382 return Diag(MacroNameTok, diag::err_defined_macro_name);

383 }

384

385

386

388 if (ShadowFlag)

389 *ShadowFlag = false;

390

391

392

393

394

395 if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&

396 !SourceMgr.isInPredefinedFile(MacroNameLoc)) {

398 if (isDefineUndef == MU_Define) {

400 }

401 else if (isDefineUndef == MU_Undef)

404

405

406

407 if (ShadowFlag)

408 *ShadowFlag = true;

409 }

411 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_id);

413 Diag(MacroNameTok, diag::warn_pp_macro_is_reserved_attribute_id)

415 }

416

417

418 return false;

419}

420

421

422

423

424

425

426

427

428

429

430void Preprocessor::ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef,

431 bool *ShadowFlag) {

432

434

435 if (MacroNameTok.is(tok::code_completion)) {

436 if (CodeComplete)

440 }

441

442 if (CheckMacroName(MacroNameTok, isDefineUndef, ShadowFlag))

443 return;

444

445

446

447 if (MacroNameTok.isNot(tok::eod)) {

448 MacroNameTok.setKind(tok::eod);

450 }

451}

452

453

454

455

456

457

458

460 bool EnableMacros) {

462

463

464

465 if (EnableMacros)

466 Lex(Tmp);

467 else

469

470

471

472 while (Tmp.is(tok::comment))

474

475 if (Tmp.is(tok::eod))

477

478

479

480

481

483 if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&

484 !CurTokenLexer)

486 Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;

488}

489

490void Preprocessor::SuggestTypoedDirective(const Token &Tok,

491 StringRef Directive) const {

492

493

494 if (getLangOpts().AsmPreprocessor) return;

495

496 std::vector Candidates = {

497 "if", "ifdef", "ifndef", "elif", "else", "endif"

498 };

499 if (LangOpts.C23 || LangOpts.CPlusPlus23)

500 Candidates.insert(Candidates.end(), {"elifdef", "elifndef"});

501

503

504 assert(Tok.getLocation().isFileID());

506 Tok.getLocation(),

507 Tok.getLocation().getLocWithOffset(Directive.size()));

508 StringRef SuggValue = *Sugg;

509

511 Diag(Tok, diag::warn_pp_invalid_directive) << 1 << SuggValue << Hint;

512 }

513}

514

515

516

517

518

519

520

521

522

523void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,

525 bool FoundNonSkipPortion,

526 bool FoundElse,

528

529

530

531

532

533

534

535

536 assert(!SkippingExcludedConditionalBlock &&

537 "calling SkipExcludedConditionalBlock recursively");

538 llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock, true);

539

540 ++NumSkipped;

541 assert(!CurTokenLexer && "Conditional PP block cannot appear in a macro!");

542 assert(CurPPLexer && "Conditional PP block must be in a file!");

543 assert(CurLexer && "Conditional PP block but no current lexer set!");

544

545 if (PreambleConditionalStack.reachedEOFWhileSkipping())

546 PreambleConditionalStack.clearSkipInfo();

547 else

548 CurPPLexer->pushConditionalLevel(IfTokenLoc, false,

549 FoundNonSkipPortion, FoundElse);

550

551

552

553 CurPPLexer->LexingRawMode = true;

554 Token Tok;

555 SourceLocation endLoc;

556

557

558

559 struct SkippingRangeStateTy {

560 Preprocessor &PP;

561

562 const char *BeginPtr = nullptr;

563 unsigned *SkipRangePtr = nullptr;

564

565 SkippingRangeStateTy(Preprocessor &PP) : PP(PP) {}

566

567 void beginLexPass() {

568 if (BeginPtr)

569 return;

570

571

572

573 BeginPtr = PP.CurLexer->getBufferLocation();

574 SkipRangePtr = &PP.RecordedSkippedRanges[BeginPtr];

575 if (*SkipRangePtr) {

576 PP.CurLexer->seek(PP.CurLexer->getCurrentBufferOffset() + *SkipRangePtr,

577 true);

578 }

579 }

580

581 void endLexPass(const char *Hashptr) {

582 if (!BeginPtr) {

583

584 assert(PP.CurLexer->isDependencyDirectivesLexer());

585 return;

586 }

587

588

589 if (!*SkipRangePtr) {

590 *SkipRangePtr = Hashptr - BeginPtr;

591 }

592 assert(*SkipRangePtr == unsigned(Hashptr - BeginPtr));

593 BeginPtr = nullptr;

594 SkipRangePtr = nullptr;

595 }

596 } SkippingRangeState(*this);

597

598 while (true) {

599 if (CurLexer->isDependencyDirectivesLexer()) {

600 CurLexer->LexDependencyDirectiveTokenWhileSkipping(Tok);

601 } else {

602 SkippingRangeState.beginLexPass();

603 while (true) {

604 CurLexer->Lex(Tok);

605

606 if (Tok.is(tok::code_completion)) {

608 if (CodeComplete)

609 CodeComplete->CodeCompleteInConditionalExclusion();

610 continue;

611 }

612

613

614 if (Tok.is(tok::eof)) {

615

616

617

618 if (PreambleConditionalStack.isRecording())

619 PreambleConditionalStack.SkipInfo.emplace(HashTokenLoc, IfTokenLoc,

620 FoundNonSkipPortion,

621 FoundElse, ElseLoc);

622 break;

623 }

624

625

627 continue;

628

629 break;

630 }

631 }

632 if (Tok.is(tok::eof))

633 break;

634

635

636

637

638 CurPPLexer->ParsingPreprocessorDirective = true;

639 if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);

640

641 assert(Tok.is(tok::hash));

642 const char *Hashptr = CurLexer->getBufferLocation() - Tok.getLength();

643 assert(CurLexer->getSourceLocation(Hashptr) == Tok.getLocation());

644

645

647

648

649

650 if (Tok.isNot(tok::raw_identifier)) {

651 CurPPLexer->ParsingPreprocessorDirective = false;

652

653 if (CurLexer) CurLexer->resetExtendedTokenMode();

654 continue;

655 }

656

657

658

659

660

661

663

664 char FirstChar = RI[0];

665 if (FirstChar >= 'a' && FirstChar <= 'z' &&

666 FirstChar != 'i' && FirstChar != 'e') {

667 CurPPLexer->ParsingPreprocessorDirective = false;

668

669 if (CurLexer) CurLexer->resetExtendedTokenMode();

670 continue;

671 }

672

673

674

675

676 char DirectiveBuf[20];

680 } else {

682 size_t IdLen = DirectiveStr.size();

683 if (IdLen >= 20) {

684 CurPPLexer->ParsingPreprocessorDirective = false;

685

686 if (CurLexer) CurLexer->resetExtendedTokenMode();

687 continue;

688 }

689 memcpy(DirectiveBuf, &DirectiveStr[0], IdLen);

690 Directive = StringRef(DirectiveBuf, IdLen);

691 }

692

693 if (Directive.starts_with("if")) {

695 if (Sub.empty() ||

696 Sub == "def" ||

697 Sub == "ndef") {

698

699

701 CurPPLexer->pushConditionalLevel(Tok.getLocation(), true,

702 false,

703 false);

704 } else {

706 }

707 } else if (Directive[0] == 'e') {

709 if (Sub == "ndif") {

710 PPConditionalInfo CondInfo;

711 CondInfo.WasSkipping = true;

712 bool InCond = CurPPLexer->popConditionalLevel(CondInfo);

713 (void)InCond;

714 assert(!InCond && "Can't be skipping if not in a conditional!");

715

716

718 SkippingRangeState.endLexPass(Hashptr);

719

720

721 CurPPLexer->LexingRawMode = false;

723 CurPPLexer->LexingRawMode = true;

724 if (Callbacks)

726 break;

727 } else {

729 }

730 } else if (Sub == "lse") {

731

732

733

734 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();

735

737 SkippingRangeState.endLexPass(Hashptr);

738

739

741 Diag(Tok, diag::pp_err_else_after_else);

742

743

745

746

747

750

751

752 CurPPLexer->LexingRawMode = false;

754 CurPPLexer->LexingRawMode = true;

755 if (Callbacks)

757 break;

758 } else {

760 }

761 } else if (Sub == "lif") {

762 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();

763

765 SkippingRangeState.endLexPass(Hashptr);

766

767

770

771

772

774

775

776

777

779 } else {

780

781

782 assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");

783 CurPPLexer->LexingRawMode = false;

784 IdentifierInfo *IfNDefMacro = nullptr;

785 DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);

786

787 if (!CurPPLexer)

788 return;

789 const bool CondValue = DER.Conditional;

790 CurPPLexer->LexingRawMode = true;

791 if (Callbacks) {

792 Callbacks->Elif(

796 }

797

798 if (CondValue) {

800 break;

801 }

802 }

803 } else if (Sub == "lifdef" ||

804 Sub == "lifndef") {

805 bool IsElifDef = Sub == "lifdef";

806 PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();

807 Token DirectiveToken = Tok;

808

810 SkippingRangeState.endLexPass(Hashptr);

811

812

813

814 unsigned DiagID;

815 if (LangOpts.CPlusPlus)

816 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive

817 : diag::ext_cxx23_pp_directive;

818 else

819 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive

820 : diag::ext_c23_pp_directive;

822

823

825 Diag(Tok, diag::pp_err_elif_after_else)

827

828

829

831

832

833

834

836 } else {

837

838

839 assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");

840 CurPPLexer->LexingRawMode = false;

841 Token MacroNameTok;

842 ReadMacroName(MacroNameTok);

843 CurPPLexer->LexingRawMode = true;

844

845

846

847 if (MacroNameTok.is(tok::eod)) {

848

849

850 continue;

851 }

852

854

856

859 MacroInfo *MI = MD.getMacroInfo();

860

861 if (Callbacks) {

862 if (IsElifDef) {

863 Callbacks->Elifdef(DirectiveToken.getLocation(), MacroNameTok,

864 MD);

865 } else {

866 Callbacks->Elifndef(DirectiveToken.getLocation(), MacroNameTok,

867 MD);

868 }

869 }

870

871 if (static_cast<bool>(MI) == IsElifDef) {

873 break;

874 }

875 }

876 } else {

878 }

879 } else {

881 }

882

883 CurPPLexer->ParsingPreprocessorDirective = false;

884

885 if (CurLexer) CurLexer->resetExtendedTokenMode();

886 }

887

888

889

890

891 CurPPLexer->LexingRawMode = false;

892

893

894

896 Callbacks->SourceRangeSkipped(

897 SourceRange(HashTokenLoc, endLoc.isValid()

898 ? endLoc

899 : CurPPLexer->getSourceLocation()),

901}

902

904 bool AllowTextual) {

905 if (!SourceMgr.isInMainFile(Loc)) {

906

907

908 FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));

909 if (auto EntryOfIncl = SourceMgr.getFileEntryRefForID(IDOfIncl)) {

910

911 return HeaderInfo.getModuleMap()

912 .findModuleForHeader(*EntryOfIncl, AllowTextual)

913 .getModule();

914 }

915 }

916

917

918

921 : HeaderInfo.lookupModule(getLangOpts().CurrentModule, Loc);

922}

923

928 IncLoc, LangOpts.ModulesValidateTextualHeaderIncludes);

929

930

931

932

933

935 while (!Loc.isInvalid() && SM.isInMainFile(Loc)) {

936 auto ID = SM.getFileID(SM.getExpansionLoc(Loc));

937 auto FE = SM.getFileEntryRefForID(ID);

938 if (!FE)

939 break;

940

941

942

943 HeaderInfo.hasModuleMap(FE->getName(), nullptr,

944 SourceMgr.isInSystemHeader(Loc));

945

946 bool InPrivateHeader = false;

947 for (auto Header : HeaderInfo.findAllModulesForHeader(*FE)) {

948 if (!Header.isAccessibleFrom(IncM)) {

949

950

951

952

953 InPrivateHeader = true;

954 continue;

955 }

956

957

959 continue;

960

961

962

964 continue;

965

966

967

968

970 return std::nullopt;

971

972

973

974

975 return *FE;

976 }

977

978

979

980 if (InPrivateHeader)

981 return std::nullopt;

982

983

984

985

987 return *FE;

988

989 Loc = SM.getIncludeLoc(ID);

990 }

991

992 return std::nullopt;

993}

994

996 SourceLocation FilenameLoc, StringRef Filename, bool isAngled,

1001 bool *IsFrameworkFound, bool SkipCache, bool OpenFile, bool CacheFailures) {

1004

1006 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);

1007

1008

1009

1011 bool BuildSystemModule = false;

1012 if (!FromDir && !FromFile) {

1015

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028 if (!FileEnt) {

1029 if (FID == SourceMgr.getMainFileID() && MainFileDir) {

1030 auto IncludeDir =

1031 HeaderInfo.getModuleMap().shouldImportRelativeToBuiltinIncludeDir(

1033 ? HeaderInfo.getModuleMap().getBuiltinDir()

1034 : MainFileDir;

1035 Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));

1037 } else if ((FileEnt = SourceMgr.getFileEntryRefForID(

1038 SourceMgr.getMainFileID()))) {

1039 auto CWD = FileMgr.getOptionalDirectoryRef(".");

1040 Includers.push_back(std::make_pair(*FileEnt, *CWD));

1041 }

1042 } else {

1043 Includers.push_back(std::make_pair(*FileEnt, FileEnt->getDir()));

1044 }

1045

1046

1047

1048

1049 if (LangOpts.MSVCCompat && !isAngled) {

1050 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {

1051 if (IsFileLexer(ISEntry))

1052 if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))

1053 Includers.push_back(std::make_pair(*FileEnt, FileEnt->getDir()));

1054 }

1055 }

1056 }

1057

1058 CurDir = CurDirLookup;

1059

1060 if (FromFile) {

1061

1062

1066 Filename, FilenameLoc, isAngled, TmpFromDir, &TmpCurDir,

1067 Includers, SearchPath, RelativePath, RequestingModule,

1068 SuggestedModule, nullptr,

1069 nullptr, SkipCache)) {

1070

1071 TmpFromDir = TmpCurDir;

1072 ++TmpFromDir;

1073 if (&FE->getFileEntry() == FromFile) {

1074

1075 FromDir = TmpFromDir;

1076 CurDir = TmpCurDir;

1077 break;

1078 }

1079 }

1080 }

1081

1082

1084 Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath,

1085 RelativePath, RequestingModule, SuggestedModule, IsMapped,

1086 IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures);

1087 if (FE)

1088 return FE;

1089

1091

1092

1093

1094 if (IsFileLexer()) {

1095 if ((CurFileEnt = CurPPLexer->getFileEntry())) {

1097 Filename, *CurFileEnt, SearchPath, RelativePath, RequestingModule,

1098 SuggestedModule)) {

1099 return FE;

1100 }

1101 }

1102 }

1103

1104 for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {

1105 if (IsFileLexer(ISEntry)) {

1106 if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {

1108 Filename, *CurFileEnt, SearchPath, RelativePath,

1109 RequestingModule, SuggestedModule)) {

1110 return FE;

1111 }

1112 }

1113 }

1114 }

1115

1116

1117 return std::nullopt;

1118}

1119

1122 const FileEntry *LookupFromFile) {

1124 if (llvm::sys::path::is_absolute(Filename)) {

1125

1127 Filename, OpenFile, true, false);

1128 return llvm::expectedToOptional(std::move(ShouldBeEntry));

1129 }

1130

1132 StringRef StartingFrom, StringRef FileName,

1133 bool RemoveInitialFileComponentFromLookupPath) {

1134 llvm::sys::path::native(StartingFrom, LookupPath);

1135 if (RemoveInitialFileComponentFromLookupPath)

1136 llvm::sys::path::remove_filename(LookupPath);

1137 if (!LookupPath.empty() &&

1138 !llvm::sys::path::is_separator(LookupPath.back())) {

1139 LookupPath.push_back(llvm::sys::path::get_separator().front());

1140 }

1142 };

1143

1144

1146

1147 if (!isAngled) {

1148 if (LookupFromFile) {

1149

1151 if (!FullFileDir.empty()) {

1152 SeparateComponents(LookupPath, FullFileDir, Filename, true);

1154 LookupPath, OpenFile, true, false);

1155 if (ShouldBeEntry)

1156 return llvm::expectedToOptional(std::move(ShouldBeEntry));

1157 llvm::consumeError(ShouldBeEntry.takeError());

1158 }

1159 }

1160

1161

1162 LookupPath.clear();

1164 if (MaybeWorkingDirEntry) {

1166 StringRef WorkingDir = WorkingDirEntry.getName();

1167 if (!WorkingDir.empty()) {

1168 SeparateComponents(LookupPath, WorkingDir, Filename, false);

1170 LookupPath, OpenFile, true, false);

1171 if (ShouldBeEntry)

1172 return llvm::expectedToOptional(std::move(ShouldBeEntry));

1173 llvm::consumeError(ShouldBeEntry.takeError());

1174 }

1175 }

1176 }

1177

1178 for (const auto &Entry : PPOpts.EmbedEntries) {

1179 LookupPath.clear();

1180 SeparateComponents(LookupPath, Entry, Filename, false);

1182 LookupPath, OpenFile, true, false);

1183 if (ShouldBeEntry)

1184 return llvm::expectedToOptional(std::move(ShouldBeEntry));

1185 llvm::consumeError(ShouldBeEntry.takeError());

1186 }

1187 return std::nullopt;

1188}

1189

1190

1191

1192

1193

1195public:

1197 : PP(pp), save(pp->DisableMacroExpansion) {

1198 if (pp->MacroExpansionInDirectivesOverride)

1199 pp->DisableMacroExpansion = false;

1200 }

1201

1203 PP->DisableMacroExpansion = save;

1204 }

1205

1206private:

1208 bool save;

1209};

1210

1211

1212

1213

1214

1215

1216

1220 if (II->getPPKeywordID() == tok::pp_define) {

1221 return HandleDefineDirective(Result,

1222 false);

1223 }

1224 if (SkippingUntilPCHThroughHeader &&

1225 II->getPPKeywordID() == tok::pp_include) {

1226 return HandleIncludeDirective(HashLoc, Result);

1227 }

1228 if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {

1230 auto *II = Result.getIdentifierInfo();

1231 if (II && II->getName() == "hdrstop")

1233 }

1234 }

1236}

1237

1238

1239

1240

1241

1243

1244

1245

1246

1247

1248 CurPPLexer->ParsingPreprocessorDirective = true;

1249 if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);

1250

1251 bool ImmediatelyAfterTopLevelIfndef =

1252 CurPPLexer->MIOpt.getImmediatelyAfterTopLevelIfndef();

1253 CurPPLexer->MIOpt.resetImmediatelyAfterTopLevelIfndef();

1254

1255 ++NumDirectives;

1256

1257

1258

1259

1260 bool ReadAnyTokensBeforeDirective =CurPPLexer->MIOpt.getHasReadAnyTokensVal();

1261

1262

1264

1265

1266

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277 if (InMacroArgs) {

1279 switch (II->getPPKeywordID()) {

1280 case tok::pp_include:

1281 case tok::pp_import:

1282 case tok::pp_include_next:

1283 case tok::pp___include_macros:

1284 case tok::pp_pragma:

1285 case tok::pp_embed:

1286 Diag(Result, diag::err_embedded_directive) << II->getName();

1287 Diag(*ArgMacro, diag::note_macro_expansion_here)

1288 << ArgMacro->getIdentifierInfo();

1290 return;

1291 default:

1292 break;

1293 }

1294 }

1295 Diag(Result, diag::ext_embedded_directive);

1296 }

1297

1298

1299

1301

1302 if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)

1304

1305 switch (Result.getKind()) {

1306 case tok::eod:

1307

1308

1309

1310 CurPPLexer->MIOpt.SetReadToken(ReadAnyTokensBeforeDirective);

1311 return;

1312 case tok::code_completion:

1314 if (CodeComplete)

1315 CodeComplete->CodeCompleteDirective(

1316 CurPPLexer->getConditionalStackDepth() > 0);

1317 return;

1318 case tok::numeric_constant:

1319

1320

1321

1324 break;

1325 return HandleDigitDirective(Result);

1326 default:

1328 if (!II) break;

1329

1330

1332 default: break;

1333

1334 case tok::pp_if:

1335 return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);

1336 case tok::pp_ifdef:

1337 return HandleIfdefDirective(Result, SavedHash, false,

1338 true );

1339 case tok::pp_ifndef:

1340 return HandleIfdefDirective(Result, SavedHash, true,

1341 ReadAnyTokensBeforeDirective);

1342 case tok::pp_elif:

1343 case tok::pp_elifdef:

1344 case tok::pp_elifndef:

1346

1347 case tok::pp_else:

1348 return HandleElseDirective(Result, SavedHash);

1349 case tok::pp_endif:

1350 return HandleEndifDirective(Result);

1351

1352

1353 case tok::pp_include:

1354

1356 case tok::pp___include_macros:

1357

1358 return HandleIncludeMacrosDirective(SavedHash.getLocation(), Result);

1359

1360

1361 case tok::pp_define:

1362 return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);

1363 case tok::pp_undef:

1364 return HandleUndefDirective();

1365

1366

1367 case tok::pp_line:

1368 return HandleLineDirective();

1369

1370

1371 case tok::pp_error:

1372 return HandleUserDiagnosticDirective(Result, false);

1373

1374

1375 case tok::pp_pragma:

1377

1378

1379 case tok::pp_import:

1381 case tok::pp_include_next:

1382 return HandleIncludeNextDirective(SavedHash.getLocation(), Result);

1383

1384 case tok::pp_warning:

1385 if (LangOpts.CPlusPlus)

1387 ? diag::warn_cxx23_compat_warning_directive

1388 : diag::ext_pp_warning_directive)

1389 << 1;

1390 else

1391 Diag(Result, LangOpts.C23 ? diag::warn_c23_compat_warning_directive

1392 : diag::ext_pp_warning_directive)

1393 << 0;

1394

1395 return HandleUserDiagnosticDirective(Result, true);

1396 case tok::pp_ident:

1397 return HandleIdentSCCSDirective(Result);

1398 case tok::pp_sccs:

1399 return HandleIdentSCCSDirective(Result);

1400 case tok::pp_embed: {

1403 return HandleEmbedDirective(SavedHash.getLocation(), Result, *FERef);

1404 return HandleEmbedDirective(SavedHash.getLocation(), Result, nullptr);

1405 }

1406 case tok::pp_assert:

1407

1408 break;

1409 case tok::pp_unassert:

1410

1411 break;

1412

1413 case tok::pp___public_macro:

1415 return HandleMacroPublicDirective(Result);

1416 break;

1417

1418 case tok::pp___private_macro:

1420 return HandleMacroPrivateDirective();

1421 break;

1422 }

1423 break;

1424 }

1425

1426

1427

1428

1429

1431 auto Toks = std::make_unique<Token[]>(2);

1432

1433 Toks[0] = SavedHash;

1435

1436

1437

1438 if (Result.is(tok::hashhash))

1439 Toks[1].setKind(tok::unknown);

1440

1441

1442

1443

1444 EnterTokenStream(std::move(Toks), 2, false, false);

1445 return;

1446 }

1447

1448

1449

1450 Diag(Result, diag::err_pp_invalid_directive) << 0;

1451

1452

1454

1455

1456}

1457

1458

1459

1462 bool IsGNULineDirective=false) {

1463 if (DigitTok.isNot(tok::numeric_constant)) {

1464 PP.Diag(DigitTok, DiagID);

1465

1466 if (DigitTok.isNot(tok::eod))

1468 return true;

1469 }

1470

1472 IntegerBuffer.resize(DigitTok.getLength());

1473 const char *DigitTokBegin = &IntegerBuffer[0];

1475 unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin, &Invalid);

1477 return true;

1478

1479

1480

1481

1482 Val = 0;

1483 for (unsigned i = 0; i != ActualLength; ++i) {

1484

1485

1486 if (DigitTokBegin[i] == '\'')

1487 continue;

1488

1489 if (isDigit(DigitTokBegin[i])) {

1491 diag::err_pp_line_digit_sequence) << IsGNULineDirective;

1493 return true;

1494 }

1495

1496 unsigned NextVal = Val*10+(DigitTokBegin[i]-'0');

1497 if (NextVal < Val) {

1498 PP.Diag(DigitTok, DiagID);

1500 return true;

1501 }

1502 Val = NextVal;

1503 }

1504

1505 if (DigitTokBegin[0] == '0' && Val)

1506 PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal)

1507 << IsGNULineDirective;

1508

1509 return false;

1510}

1511

1512

1513

1514

1515

1516

1517

1518

1519void Preprocessor::HandleLineDirective() {

1520

1521

1522 Token DigitTok;

1523 Lex(DigitTok);

1524

1525

1526 unsigned LineNo;

1527 if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer,*this))

1528 return;

1529

1530 if (LineNo == 0)

1531 Diag(DigitTok, diag::ext_pp_line_zero);

1532

1533

1534

1535 unsigned LineLimit = 32768U;

1536 if (LangOpts.C99 || LangOpts.CPlusPlus11)

1537 LineLimit = 2147483648U;

1538 if (LineNo >= LineLimit)

1539 Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;

1540 else if (LangOpts.CPlusPlus11 && LineNo >= 32768U)

1541 Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);

1542

1543 int FilenameID = -1;

1544 Token StrTok;

1545 Lex(StrTok);

1546

1547

1548

1549 if (StrTok.is(tok::eod))

1550 ;

1551 else if (StrTok.isNot(tok::string_literal)) {

1552 Diag(StrTok, diag::err_pp_line_invalid_filename);

1554 return;

1556 Diag(StrTok, diag::err_invalid_string_udl);

1558 return;

1559 } else {

1560

1561 StringLiteralParser Literal(StrTok, *this);

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

1565 return;

1566 }

1568 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);

1570 return;

1571 }

1572 FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());

1573

1574

1575

1577 }

1578

1579

1580

1581

1582

1583

1585 SourceMgr.getFileCharacteristic(DigitTok.getLocation());

1586

1587 SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, false,

1588 false, FileKind);

1589

1590 if (Callbacks)

1591 Callbacks->FileChanged(CurPPLexer->getSourceLocation(),

1593}

1594

1595

1596

1600 unsigned FlagVal;

1602 PP.Lex(FlagTok);

1603 if (FlagTok.is(tok::eod)) return false;

1604 if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))

1605 return true;

1606

1607 if (FlagVal == 1) {

1608 IsFileEntry = true;

1609

1610 PP.Lex(FlagTok);

1611 if (FlagTok.is(tok::eod)) return false;

1612 if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))

1613 return true;

1614 } else if (FlagVal == 2) {

1615 IsFileExit = true;

1616

1618

1619

1621 SM.getDecomposedExpansionLoc(FlagTok.getLocation()).first;

1624 return true;

1625

1626

1627

1630 SM.getDecomposedExpansionLoc(IncLoc).first != CurFileID) {

1631 PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_pop);

1633 return true;

1634 }

1635

1636 PP.Lex(FlagTok);

1637 if (FlagTok.is(tok::eod)) return false;

1638 if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP))

1639 return true;

1640 }

1641

1642

1643 if (FlagVal != 3) {

1644 PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);

1646 return true;

1647 }

1648

1650

1651 PP.Lex(FlagTok);

1652 if (FlagTok.is(tok::eod)) return false;

1653 if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP))

1654 return true;

1655

1656

1657 if (FlagVal != 4) {

1658 PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);

1660 return true;

1661 }

1662

1664

1665 PP.Lex(FlagTok);

1666 if (FlagTok.is(tok::eod)) return false;

1667

1668

1669 PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag);

1671 return true;

1672}

1673

1674

1675

1676

1677

1678

1679

1680

1681void Preprocessor::HandleDigitDirective(Token &DigitTok) {

1682

1683

1684 unsigned LineNo;

1685 if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,

1686 *this, true))

1687 return;

1688

1689 Token StrTok;

1690 Lex(StrTok);

1691

1692 bool IsFileEntry = false, IsFileExit = false;

1693 int FilenameID = -1;

1695

1696

1697

1698 if (StrTok.is(tok::eod)) {

1699 Diag(StrTok, diag::ext_pp_gnu_line_directive);

1700

1701 FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());

1702 } else if (StrTok.isNot(tok::string_literal)) {

1703 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);

1705 return;

1707 Diag(StrTok, diag::err_invalid_string_udl);

1709 return;

1710 } else {

1711

1712 StringLiteralParser Literal(StrTok, *this);

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

1716 return;

1717 }

1719 Diag(StrTok, diag::err_pp_linemarker_invalid_filename);

1721 return;

1722 }

1723

1724

1726 return;

1727 if (!SourceMgr.isInPredefinedFile(DigitTok.getLocation()))

1728 Diag(StrTok, diag::ext_pp_gnu_line_directive);

1729

1730

1731

1732 if (!(IsFileExit && Literal.GetString().empty()))

1733 FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());

1734 }

1735

1736

1737 SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, IsFileEntry,

1738 IsFileExit, FileKind);

1739

1740

1741

1742

1743 if (Callbacks) {

1745 if (IsFileEntry)

1747 else if (IsFileExit)

1749

1750 Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);

1751 }

1752}

1753

1754

1755

1756void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,

1757 bool isWarning) {

1758

1759

1760

1761

1762

1763 SmallString<128> Message;

1764 CurLexer->ReadToEndOfLine(&Message);

1765

1766

1767

1768 StringRef Msg = Message.str().ltrim(' ');

1769

1770 if (isWarning)

1771 Diag(Tok, diag::pp_hash_warning) << Msg;

1772 else

1773 Diag(Tok, diag::err_pp_hash_error) << Msg;

1774}

1775

1776

1777

1778void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {

1779

1780 Diag(Tok, diag::ext_pp_ident_directive);

1781

1782

1783 Token StrTok;

1784 Lex(StrTok);

1785

1786

1787 if (StrTok.isNot(tok::string_literal) &&

1788 StrTok.isNot(tok::wide_string_literal)) {

1789 Diag(StrTok, diag::err_pp_malformed_ident);

1790 if (StrTok.isNot(tok::eod))

1792 return;

1793 }

1794

1796 Diag(StrTok, diag::err_invalid_string_udl);

1798 return;

1799 }

1800

1801

1803

1804 if (Callbacks) {

1809 }

1810}

1811

1812

1813void Preprocessor::HandleMacroPublicDirective(Token &Tok) {

1814 Token MacroNameTok;

1815 ReadMacroName(MacroNameTok, MU_Undef);

1816

1817

1818 if (MacroNameTok.is(tok::eod))

1819 return;

1820

1821

1823

1825

1827

1828

1829 if (!MD) {

1830 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;

1831 return;

1832 }

1833

1834

1836 MacroNameTok.getLocation(), true));

1837}

1838

1839

1840void Preprocessor::HandleMacroPrivateDirective() {

1841 Token MacroNameTok;

1842 ReadMacroName(MacroNameTok, MU_Undef);

1843

1844

1845 if (MacroNameTok.is(tok::eod))

1846 return;

1847

1848

1850

1852

1854

1855

1856 if (!MD) {

1857 Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;

1858 return;

1859 }

1860

1861

1863 MacroNameTok.getLocation(), false));

1864}

1865

1866

1867

1868

1869

1870

1871

1872

1873

1874

1875

1877 StringRef &Buffer) {

1878

1879 assert(!Buffer.empty() && "Can't have tokens with empty spellings!");

1880

1881

1882

1883

1884

1885

1886

1887

1888

1889

1890 bool isAngled;

1891 if (Buffer[0] == '<') {

1892 if (Buffer.back() != '>') {

1893 Diag(Loc, diag::err_pp_expects_filename);

1894 Buffer = StringRef();

1895 return true;

1896 }

1897 isAngled = true;

1898 } else if (Buffer[0] == '"') {

1899 if (Buffer.back() != '"') {

1900 Diag(Loc, diag::err_pp_expects_filename);

1901 Buffer = StringRef();

1902 return true;

1903 }

1904 isAngled = false;

1905 } else {

1906 Diag(Loc, diag::err_pp_expects_filename);

1907 Buffer = StringRef();

1908 return true;

1909 }

1910

1911

1912 if (Buffer.size() <= 2) {

1913 Diag(Loc, diag::err_pp_empty_filename);

1914 Buffer = StringRef();

1915 return true;

1916 }

1917

1918

1919 Buffer = Buffer.substr(1, Buffer.size()-2);

1920 return isAngled;

1921}

1922

1923

1926 void *AnnotationVal) {

1927

1928

1929 auto Tok = std::make_unique<Token[]>(1);

1930 Tok[0].startToken();

1931 Tok[0].setKind(Kind);

1932 Tok[0].setLocation(Range.getBegin());

1933 Tok[0].setAnnotationEndLoc(Range.getEnd());

1934 Tok[0].setAnnotationValue(AnnotationVal);

1935 EnterTokenStream(std::move(Tok), 1, true, false);

1936}

1937

1938

1939

1941 Token &IncludeTok,

1945 for (size_t I = 0, N = Path.size(); I != N; ++I) {

1946 if (I)

1947 PathString += '.';

1948 PathString += Path[I].getIdentifierInfo()->getName();

1949 }

1950

1951 int IncludeKind = 0;

1953 case tok::pp_include:

1954 IncludeKind = 0;

1955 break;

1956

1957 case tok::pp_import:

1958 IncludeKind = 1;

1959 break;

1960

1961 case tok::pp_include_next:

1962 IncludeKind = 2;

1963 break;

1964

1965 case tok::pp___include_macros:

1966 IncludeKind = 3;

1967 break;

1968

1969 default:

1970 llvm_unreachable("unknown include directive kind");

1971 }

1972

1973 PP.Diag(HashLoc, diag::remark_pp_include_directive_modular_translation)

1974 << IncludeKind << PathString;

1975}

1976

1977

1978

1979

1981 StringRef RealPathName,

1982 llvm::sys::path::Style Separator) {

1983 auto RealPathComponentIter = llvm::sys::path::rbegin(RealPathName);

1984 auto RealPathComponentEnd = llvm::sys::path::rend(RealPathName);

1985 int Cnt = 0;

1986 bool SuggestReplacement = false;

1987

1988 auto IsSep = [Separator](StringRef Component) {

1989 return Component.size() == 1 &&

1990 llvm::sys::path::is_separator(Component[0], Separator);

1991 };

1992

1993

1994

1995 for (auto &Component : llvm::reverse(Components)) {

1996 if ("." == Component) {

1997 } else if (".." == Component) {

1998 ++Cnt;

1999 } else if (Cnt) {

2000 --Cnt;

2001 } else if (RealPathComponentIter != RealPathComponentEnd) {

2002 if (!IsSep(Component) && !IsSep(*RealPathComponentIter) &&

2003 Component != *RealPathComponentIter) {

2004

2005

2006

2007 SuggestReplacement =

2008 RealPathComponentIter->equals_insensitive(Component);

2009 if (!SuggestReplacement)

2010 break;

2011 Component = *RealPathComponentIter;

2012 }

2013 ++RealPathComponentIter;

2014 }

2015 }

2016 return SuggestReplacement;

2017}

2018

2025 Module *ShadowingModule = nullptr;

2027 ShadowingModule))

2028 return false;

2029

2031 Diags.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)

2033 } else if (ShadowingModule) {

2034 Diags.Report(M.DefinitionLoc, diag::err_module_shadowed) << M.Name;

2036 diag::note_previous_definition);

2037 } else {

2038

2039

2040 Diags.Report(M.DefinitionLoc, diag::err_module_unavailable)

2043 }

2044 return true;

2045}

2046

2047std::pair<ConstSearchDirIterator, const FileEntry *>

2048Preprocessor::getIncludeNextStart(const Token &IncludeNextTok) const {

2049

2050

2051

2053 const FileEntry *LookupFromFile = nullptr;

2054

2056

2057

2058

2060 Lookup = nullptr;

2061 Diag(IncludeNextTok, diag::pp_include_next_in_primary);

2062 } else if (CurLexerSubmodule) {

2063

2064

2065 assert(CurPPLexer && "#include_next directive in macro?");

2066 if (auto FE = CurPPLexer->getFileEntry())

2067 LookupFromFile = *FE;

2068 Lookup = nullptr;

2069 } else if (!Lookup) {

2070

2071

2072

2073

2074 Diag(IncludeNextTok, diag::pp_include_next_absolute_path);

2075 } else {

2076

2077 ++Lookup;

2078 }

2079

2080 return {Lookup, LookupFromFile};

2081}

2082

2083

2084

2085

2086

2087

2088void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,

2089 Token &IncludeTok,

2091 const FileEntry *LookupFromFile) {

2092 Token FilenameTok;

2094 return;

2095

2096 if (FilenameTok.isNot(tok::header_name)) {

2097 if (FilenameTok.is(tok::identifier) && PPOpts.SingleFileParseMode) {

2098

2099

2100

2101

2103 return;

2104 }

2105

2106 Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);

2107 if (FilenameTok.isNot(tok::eod))

2109 return;

2110 }

2111

2112

2113

2114

2115

2116 SourceLocation EndLoc =

2118

2119 auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,

2120 EndLoc, LookupFrom, LookupFromFile);

2121 switch (Action.Kind) {

2122 case ImportAction::None:

2123 case ImportAction::SkippedModuleImport:

2124 break;

2125 case ImportAction::ModuleBegin:

2127 tok::annot_module_begin, Action.ModuleForHeader);

2128 break;

2129 case ImportAction::HeaderUnitImport:

2131 Action.ModuleForHeader);

2132 break;

2133 case ImportAction::ModuleImport:

2135 tok::annot_module_include, Action.ModuleForHeader);

2136 break;

2137 case ImportAction::Failure:

2138 assert(TheModuleLoader.HadFatalFailure &&

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

2140 TheModuleLoader.HadFatalFailure = true;

2141 IncludeTok.setKind(tok::eof);

2142 CurLexer->cutOffLexing();

2143 return;

2144 }

2145}

2146

2150 const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl,

2152 const FileEntry *LookupFromFile, StringRef &LookupFilename,

2155 auto DiagnoseHeaderInclusion = [&](FileEntryRef FE) {

2156 if (LangOpts.AsmPreprocessor)

2157 return;

2158

2160 FilenameLoc, LangOpts.ModulesValidateTextualHeaderIncludes);

2161 bool RequestingModuleIsModuleInterface =

2162 !SourceMgr.isInMainFile(FilenameLoc);

2163

2164 HeaderInfo.getModuleMap().diagnoseHeaderInclusion(

2165 RequestingModule, RequestingModuleIsModuleInterface, FilenameLoc,

2166 Filename, FE);

2167 };

2168

2170 FilenameLoc, LookupFilename, isAngled, LookupFrom, LookupFromFile, CurDir,

2171 Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,

2172 &SuggestedModule, &IsMapped, &IsFrameworkFound);

2174 DiagnoseHeaderInclusion(*File);

2175 return File;

2176 }

2177

2178

2179 if (Callbacks && Callbacks->FileNotFound(Filename))

2180 return std::nullopt;

2181

2182 if (SuppressIncludeNotFoundError)

2183 return std::nullopt;

2184

2185

2186

2187

2188 if (isAngled) {

2190 FilenameLoc, LookupFilename, false, LookupFrom, LookupFromFile, CurDir,

2191 Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,

2192 &SuggestedModule, &IsMapped,

2193 nullptr);

2195 DiagnoseHeaderInclusion(*File);

2196 Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal)

2197 << Filename << IsImportDecl

2199 "\"" + Filename.str() + "\"");

2200 return File;

2201 }

2202 }

2203

2204

2205

2206 StringRef OriginalFilename = Filename;

2207 if (LangOpts.SpellChecking) {

2208

2209

2210 auto CorrectTypoFilename = [](llvm::StringRef Filename) {

2212 while (!Filename.empty() && isAlphanumeric(Filename.back())) {

2213 Filename = Filename.drop_back();

2214 }

2215 return Filename;

2216 };

2217 StringRef TypoCorrectionName = CorrectTypoFilename(Filename);

2218 StringRef TypoCorrectionLookupName = CorrectTypoFilename(LookupFilename);

2219

2221 FilenameLoc, TypoCorrectionLookupName, isAngled, LookupFrom,

2222 LookupFromFile, CurDir, Callbacks ? &SearchPath : nullptr,

2223 Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped,

2224 nullptr);

2226 DiagnoseHeaderInclusion(*File);

2227 auto Hint =

2229 FilenameRange, "<" + TypoCorrectionName.str() + ">")

2230 : FixItHint::CreateReplacement(

2231 FilenameRange, "\"" + TypoCorrectionName.str() + "\"");

2232 Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)

2233 << OriginalFilename << TypoCorrectionName << Hint;

2234

2235

2236 Filename = TypoCorrectionName;

2237 LookupFilename = TypoCorrectionLookupName;

2238 return File;

2239 }

2240 }

2241

2242

2243 assert(File && "expected missing file");

2244 Diag(FilenameTok, diag::err_pp_file_not_found)

2245 << OriginalFilename << FilenameRange;

2246 if (IsFrameworkFound) {

2247 size_t SlashPos = OriginalFilename.find('/');

2248 assert(SlashPos != StringRef::npos &&

2249 "Include with framework name should have '/' in the filename");

2250 StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);

2251 FrameworkCacheEntry &CacheEntry =

2252 HeaderInfo.LookupFrameworkCache(FrameworkName);

2253 assert(CacheEntry.Directory && "Found framework should be in cache");

2254 Diag(FilenameTok, diag::note_pp_framework_without_header)

2255 << OriginalFilename.substr(SlashPos + 1) << FrameworkName

2257 }

2258

2259 return std::nullopt;

2260}

2261

2262

2263

2264

2265

2266

2267

2268

2269

2270

2271

2272

2273

2274Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(

2277 const FileEntry *LookupFromFile) {

2278 SmallString<128> FilenameBuffer;

2279 StringRef Filename = getSpelling(FilenameTok, FilenameBuffer);

2280 SourceLocation CharEnd = FilenameTok.getEndLoc();

2281

2282 CharSourceRange FilenameRange

2284 StringRef OriginalFilename = Filename;

2285 bool isAngled =

2287

2288

2289

2290 if (Filename.empty())

2291 return {ImportAction::None};

2292

2293 bool IsImportDecl = HashLoc.isInvalid();

2294 SourceLocation StartLoc = IsImportDecl ? IncludeTok.getLocation() : HashLoc;

2295

2296

2297 if (PragmaARCCFCodeAuditedInfo.getLoc().isValid()) {

2298 Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;

2299 Diag(PragmaARCCFCodeAuditedInfo.getLoc(), diag::note_pragma_entered_here);

2300

2301

2302 PragmaARCCFCodeAuditedInfo = IdentifierLoc();

2303 }

2304

2305

2306 if (PragmaAssumeNonNullLoc.isValid()) {

2307 Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;

2308 Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);

2309

2310

2311 PragmaAssumeNonNullLoc = SourceLocation();

2312 }

2313

2314 if (HeaderInfo.HasIncludeAliasMap()) {

2315

2316

2317

2318 StringRef NewName = HeaderInfo.MapHeaderToIncludeAlias(OriginalFilename);

2319 if (!NewName.empty())

2320 Filename = NewName;

2321 }

2322

2323

2324 bool IsMapped = false;

2325 bool IsFrameworkFound = false;

2327 SmallString<1024> SearchPath;

2328 SmallString<1024> RelativePath;

2329

2330

2331 ModuleMap::KnownHeader SuggestedModule;

2332 SourceLocation FilenameLoc = FilenameTok.getLocation();

2333 StringRef LookupFilename = Filename;

2334

2335

2336

2337 SmallString<128> NormalizedPath;

2338 llvm::sys::path::Style BackslashStyle = llvm::sys::path::Style::native;

2339 if (is_style_posix(BackslashStyle) && LangOpts.MicrosoftExt) {

2340 NormalizedPath = Filename.str();

2341 llvm::sys::path::native(NormalizedPath);

2342 LookupFilename = NormalizedPath;

2343 BackslashStyle = llvm::sys::path::Style::windows;

2344 }

2345

2347 &CurDir, Filename, FilenameLoc, FilenameRange, FilenameTok,

2348 IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,

2349 LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);

2350

2353 SkippingUntilPCHThroughHeader = false;

2354 return {ImportAction::None};

2355 }

2356

2357

2358

2359

2360

2361

2362

2363

2364

2365

2366

2367

2368

2369

2370

2371

2372 enum { Enter, Import, Skip, IncludeLimitReached } Action = Enter;

2373

2374 if (PPOpts.SingleFileParseMode)

2375 Action = IncludeLimitReached;

2376

2377

2378

2379

2380 if (Action == Enter && HasReachedMaxIncludeDepth && File &&

2382 Action = IncludeLimitReached;

2383

2384

2385

2386

2388

2389 bool MaybeTranslateInclude = Action == Enter && File && ModuleToImport &&

2391

2392

2393 bool UsableHeaderUnit = false;

2394 if (getLangOpts().CPlusPlusModules && ModuleToImport &&

2396 if (TrackGMFState.inGMF() || IsImportDecl)

2397 UsableHeaderUnit = true;

2398 else if (!IsImportDecl) {

2399

2400 ModuleToImport = nullptr;

2401 }

2402 }

2403

2404 bool UsableClangHeaderModule =

2406 ModuleToImport && !ModuleToImport->isHeaderUnit();

2407

2408

2409

2410

2411 if (MaybeTranslateInclude && (UsableHeaderUnit || UsableClangHeaderModule)) {

2412

2413

2414

2415

2419 diag::note_implicit_top_level_module_import_here)

2421 return {ImportAction::None};

2422 }

2423

2424

2425

2426

2427 SmallVector<IdentifierLoc, 2> Path;

2428 for (Module *Mod = ModuleToImport; Mod; Mod = Mod->Parent)

2429 Path.emplace_back(FilenameTok.getLocation(),

2431 std::reverse(Path.begin(), Path.end());

2432

2433

2434 if (!IsImportDecl)

2436

2437

2438

2439

2440

2441 ModuleLoadResult Imported = TheModuleLoader.loadModule(

2443 true);

2444 assert((Imported == nullptr || Imported == ModuleToImport) &&

2445 "the imported module is different than the suggested one");

2446

2447 if (Imported) {

2451 static_cast<Module *>(Imported)->getTopLevelModule());

2452

2453

2454

2455

2456 ModuleToImport = nullptr;

2458

2459

2460 } else {

2461

2463

2464 Token &Result = IncludeTok;

2465 assert(CurLexer && "#include but no current lexer set!");

2466 Result.startToken();

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

2468 CurLexer->cutOffLexing();

2469 }

2470 return {ImportAction::None};

2471 }

2472 }

2473

2474

2475

2476

2478 SourceMgr.getFileCharacteristic(FilenameTok.getLocation());

2480 FileCharacter = std::max(HeaderInfo.getFileDirFlavor(*File), FileCharacter);

2481

2482

2483

2484

2485

2486

2487 bool EnterOnce =

2488 IsImportDecl ||

2490

2491 bool IsFirstIncludeOfFile = false;

2492

2493

2494

2495 if (Action == Enter && File &&

2496 !HeaderInfo.ShouldEnterIncludeFile(*this, *File, EnterOnce,

2498 IsFirstIncludeOfFile)) {

2499

2500

2501

2502

2503

2504

2505

2506

2507

2508

2509 if (UsableHeaderUnit && getLangOpts().CompilingPCH)

2510 Action = TrackGMFState.inGMF() ? Import : Skip;

2511 else

2512 Action = (ModuleToImport && getLangOpts().CompilingPCH) ? Import : Skip;

2513 }

2514

2515

2516

2517

2518

2519

2520 if (Action == Enter && File && PreambleConditionalStack.isRecording() &&

2521 SourceMgr.isMainFile(File->getFileEntry())) {

2523 diag::err_pp_including_mainfile_in_preamble);

2524 return {ImportAction::None};

2525 }

2526

2527 if (Callbacks && !IsImportDecl) {

2528

2529

2530 Callbacks->InclusionDirective(HashLoc, IncludeTok, LookupFilename, isAngled,

2531 FilenameRange, File, SearchPath, RelativePath,

2532 SuggestedModule.getModule(), Action == Import,

2533 FileCharacter);

2535 Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);

2536 }

2537

2539 return {ImportAction::None};

2540

2541

2542

2543 if (IsImportDecl && !ModuleToImport) {

2544 Diag(FilenameTok, diag::err_header_import_not_header_unit)

2545 << OriginalFilename << File->getName();

2546 return {ImportAction::None};

2547 }

2548

2549

2550

2551 const bool CheckIncludePathPortability =

2552 !IsMapped && File->getFileEntry().tryGetRealPathName().empty();

2553

2554 if (CheckIncludePathPortability) {

2555 StringRef Name = LookupFilename;

2556 StringRef NameWithoriginalSlashes = Filename;

2557#if defined(_WIN32)

2558

2559

2560 bool NameWasUNC = Name.consume_front("\\\\?\\");

2561 NameWithoriginalSlashes.consume_front("\\\\?\\");

2562#endif

2563 StringRef RealPathName = File->getFileEntry().tryGetRealPathName();

2564 SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name),

2565 llvm::sys::path::end(Name));

2566#if defined(_WIN32)

2567

2568

2569

2570

2571

2572

2573

2574

2575

2576

2577 SmallString<128> FixedDriveRealPath;

2578 if (llvm::sys::path::is_absolute(Name) &&

2579 llvm::sys::path::is_absolute(RealPathName) &&

2582 assert(Components.size() >= 3 && "should have drive, backslash, name");

2583 assert(Components[0].size() == 2 && "should start with drive");

2584 assert(Components[0][1] == ':' && "should have colon");

2585 FixedDriveRealPath = (Name.substr(0, 1) + RealPathName.substr(1)).str();

2586 RealPathName = FixedDriveRealPath;

2587 }

2588#endif

2589

2590 if (trySimplifyPath(Components, RealPathName, BackslashStyle)) {

2591 SmallString<128> Path;

2592 Path.reserve(Name.size()+2);

2593 Path.push_back(isAngled ? '<' : '"');

2594

2595 const auto IsSep = [BackslashStyle](char c) {

2596 return llvm::sys::path::is_separator(c, BackslashStyle);

2597 };

2598

2599 for (auto Component : Components) {

2600

2601

2602

2603

2604

2605

2606

2607

2608

2609

2610

2611 if (!(Component.size() == 1 && IsSep(Component[0])))

2612 Path.append(Component);

2613 else if (Path.size() != 1)

2614 continue;

2615

2616

2617 if (Path.size() > NameWithoriginalSlashes.size()) {

2618 Path.push_back(isAngled ? '>' : '"');

2619 continue;

2620 }

2621 assert(IsSep(NameWithoriginalSlashes[Path.size()-1]));

2622 do

2623 Path.push_back(NameWithoriginalSlashes[Path.size()-1]);

2624 while (Path.size() <= NameWithoriginalSlashes.size() &&

2625 IsSep(NameWithoriginalSlashes[Path.size()-1]));

2626 }

2627

2628#if defined(_WIN32)

2629

2630 if (NameWasUNC)

2631 Path = (Path.substr(0, 1) + "\\\\?\\" + Path.substr(1)).str();

2632#endif

2633

2634

2635

2636 auto DiagId =

2638 ? diag::pp_nonportable_path

2639 : diag::pp_nonportable_system_path;

2640 Diag(FilenameTok, DiagId) << Path <<

2642 }

2643 }

2644

2645 switch (Action) {

2647

2648 if (ModuleToImport)

2649 return {ImportAction::SkippedModuleImport, ModuleToImport};

2650 return {ImportAction::None};

2651

2652 case IncludeLimitReached:

2653

2654

2655 return {ImportAction::None};

2656

2658

2659 assert(ModuleToImport && "no module to import");

2660

2662

2664 tok::pp___include_macros)

2665 return {ImportAction::None};

2666

2667 return {ImportAction::ModuleImport, ModuleToImport};

2668 }

2669

2670 case Enter:

2671 break;

2672 }

2673

2674

2675 if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {

2676 Diag(FilenameTok, diag::err_pp_include_too_deep);

2677 HasReachedMaxIncludeDepth = true;

2678 return {ImportAction::None};

2679 }

2680

2682 Diag(FilenameTok, diag::warn_pp_include_angled_in_module_purview)

2684

2685

2686 SourceLocation IncludePos = FilenameTok.getLocation();

2687

2688

2690 IncludePos = SourceMgr.getExpansionRange(IncludePos).getEnd();

2691 FileID FID = SourceMgr.createFileID(*File, IncludePos, FileCharacter);

2693 TheModuleLoader.HadFatalFailure = true;

2694 return ImportAction::Failure;

2695 }

2696

2697

2699 IsFirstIncludeOfFile))

2700 return {ImportAction::None};

2701

2702

2703

2704 if (ModuleToImport && !ModuleToImport->isHeaderUnit()) {

2706

2707

2709 diag::err_module_build_shadowed_submodule)

2712 diag::note_previous_definition);

2713 return {ImportAction::None};

2714 }

2715

2716

2717

2718

2719

2720

2721

2722

2725 return {ImportAction::None};

2726

2727 assert(!CurLexerSubmodule && "should not have marked this as a module yet");

2728 CurLexerSubmodule = ModuleToImport;

2729

2730

2731

2732 EnterSubmodule(ModuleToImport, EndLoc, false);

2733

2734

2735

2736

2737

2738 return {ImportAction::ModuleBegin, ModuleToImport};

2739 }

2740

2741 assert(!IsImportDecl && "failed to diagnose missing module for import decl");

2742 return {ImportAction::None};

2743}

2744

2745

2746

2747void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,

2748 Token &IncludeNextTok) {

2749 Diag(IncludeNextTok, diag::ext_pp_include_next_directive);

2750

2752 const FileEntry *LookupFromFile;

2753 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(IncludeNextTok);

2754

2755 return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup,

2756 LookupFromFile);

2757}

2758

2759

2760void Preprocessor::HandleMicrosoftImportDirective(Token &Tok) {

2761

2762

2763

2764

2765

2766 Diag(Tok, diag::err_pp_import_directive_ms );

2767

2768

2769

2771}

2772

2773

2774

2775void Preprocessor::HandleImportDirective(SourceLocation HashLoc,

2776 Token &ImportTok) {

2777 if (!LangOpts.ObjC) {

2778 if (LangOpts.MSVCCompat)

2779 return HandleMicrosoftImportDirective(ImportTok);

2780 Diag(ImportTok, diag::ext_pp_import_directive);

2781 }

2782 return HandleIncludeDirective(HashLoc, ImportTok);

2783}

2784

2785

2786

2787

2788

2789void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,

2790 Token &IncludeMacrosTok) {

2791

2792

2793 SourceLocation Loc = IncludeMacrosTok.getLocation();

2794 if (SourceMgr.getBufferName(Loc) != "") {

2796 diag::pp_include_macros_out_of_predefines);

2798 return;

2799 }

2800

2801

2802

2803 HandleIncludeDirective(HashLoc, IncludeMacrosTok);

2804

2805 Token TmpTok;

2806 do {

2807 Lex(TmpTok);

2808 assert(TmpTok.isNot(tok::eof) && "Didn't find end of -imacros!");

2809 } while (TmpTok.isNot(tok::hashhash));

2810}

2811

2812

2813

2814

2815

2816

2817

2818

2819

2820bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {

2821 SmallVector<IdentifierInfo*, 32> Parameters;

2822

2823 while (true) {

2826 case tok::r_paren:

2827

2828 if (Parameters.empty())

2829 return false;

2830

2831 Diag(Tok, diag::err_pp_expected_ident_in_arg_list);

2832 return true;

2833 case tok::ellipsis:

2834 if (!LangOpts.C99)

2835 Diag(Tok, LangOpts.CPlusPlus11 ?

2836 diag::warn_cxx98_compat_variadic_macro :

2837 diag::ext_variadic_macro);

2838

2839

2840 if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus) {

2841 Diag(Tok, diag::ext_pp_opencl_variadic_macros);

2842 }

2843

2844

2846 if (Tok.isNot(tok::r_paren)) {

2847 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);

2848 return true;

2849 }

2850

2851 Parameters.push_back(Ident__VA_ARGS__);

2854 return false;

2855 case tok::eod:

2856 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);

2857 return true;

2858 default:

2859

2860

2862 if (!II) {

2863

2864 Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);

2865 return true;

2866 }

2867

2868

2869

2870 if (llvm::is_contained(Parameters, II)) {

2871 Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;

2872 return true;

2873 }

2874

2875

2877

2878

2880

2882 default:

2883 Diag(Tok, diag::err_pp_expected_comma_in_arg_list);

2884 return true;

2885 case tok::r_paren:

2887 return false;

2888 case tok::comma:

2889 break;

2890 case tok::ellipsis:

2891

2892 Diag(Tok, diag::ext_named_variadic_macro);

2893

2894

2896 if (Tok.isNot(tok::r_paren)) {

2897 Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);

2898 return true;

2899 }

2900

2903 return false;

2904 }

2905 }

2906 }

2907}

2908

2913

2914

2916 return true;

2917

2918

2919

2920

2921

2922

2926 return false;

2927 StringRef ValueText = II->getName();

2928 StringRef TrimmedValue = ValueText;

2929 if (!ValueText.starts_with("__")) {

2930 if (ValueText.starts_with("_"))

2931 TrimmedValue = TrimmedValue.drop_front(1);

2932 else

2933 return false;

2934 } else {

2935 TrimmedValue = TrimmedValue.drop_front(2);

2936 if (TrimmedValue.ends_with("__"))

2937 TrimmedValue = TrimmedValue.drop_back(2);

2938 }

2939 return TrimmedValue == MacroText;

2940 } else {

2941 return false;

2942 }

2943 }

2944

2945

2946 return MacroName.isOneOf(tok::kw_extern, tok::kw_inline, tok::kw_static,

2947 tok::kw_const) &&

2949}

2950

2951

2952

2953

2954

2955

2956

2957

2958

2959MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(

2960 const Token &MacroNameTok, const bool ImmediatelyAfterHeaderGuard) {

2961

2962 Token LastTok = MacroNameTok;

2963

2965

2966 Token Tok;

2968

2969

2970 auto _ = llvm::make_scope_exit([&]() {

2971

2972 if (CurLexer->ParsingPreprocessorDirective)

2974 });

2975

2976

2977

2979

2980

2981

2982

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

2984 if (ImmediatelyAfterHeaderGuard) {

2985

2986 CurPPLexer->MIOpt.SetDefinedMacro(MacroNameTok.getIdentifierInfo(),

2988 }

2989

2991

2992

2994 } else if (Tok.is(tok::l_paren)) {

2995

2997 if (ReadMacroParameterList(MI, LastTok))

2998 return nullptr;

2999

3000

3001

3002

3003

3004

3007 }

3008

3009

3011 } else if (LangOpts.C99 || LangOpts.CPlusPlus11) {

3012

3013

3014 Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);

3015 } else {

3016

3017

3018

3019

3020

3021

3023 if (Tok.is(tok::at))

3025 else if (Tok.is(tok::unknown)) {

3026

3027

3028

3030 }

3032 Diag(Tok, diag::ext_missing_whitespace_after_macro_name);

3033 else

3034 Diag(Tok, diag::warn_missing_whitespace_after_macro_name);

3035 }

3036

3037 if (Tok.is(tok::eod))

3038 LastTok = Tok;

3039

3040 SmallVector<Token, 16> Tokens;

3041

3042

3044

3045 while (Tok.isNot(tok::eod)) {

3046 LastTok = Tok;

3047 Tokens.push_back(Tok);

3048

3050 }

3051 } else {

3052

3053

3054

3055

3057

3058 while (Tok.isNot(tok::eod)) {

3059 LastTok = Tok;

3060

3061 if (Tok.isOneOf(tok::hash, tok::hashat, tok::hashhash)) {

3062 Tokens.push_back(Tok);

3063

3064 if (VAOCtx.isVAOptToken(Tok)) {

3065

3066 if (VAOCtx.isInVAOpt()) {

3067 Diag(Tok, diag::err_pp_vaopt_nested_use);

3068 return nullptr;

3069 }

3070

3072 if (Tok.isNot(tok::l_paren)) {

3073 Diag(Tok, diag::err_pp_missing_lparen_in_vaopt_use);

3074 return nullptr;

3075 }

3076 Tokens.push_back(Tok);

3077 VAOCtx.sawVAOptFollowedByOpeningParens(Tok.getLocation());

3079 if (Tok.is(tok::hashhash)) {

3080 Diag(Tok, diag::err_vaopt_paste_at_start);

3081 return nullptr;

3082 }

3083 continue;

3084 } else if (VAOCtx.isInVAOpt()) {

3085 if (Tok.is(tok::r_paren)) {

3086 if (VAOCtx.sawClosingParen()) {

3087 assert(Tokens.size() >= 3 &&

3088 "Must have seen at least __VA_OPT__( "

3089 "and a subsequent tok::r_paren");

3090 if (Tokens[Tokens.size() - 2].is(tok::hashhash)) {

3091 Diag(Tok, diag::err_vaopt_paste_at_end);

3092 return nullptr;

3093 }

3094 }

3095 } else if (Tok.is(tok::l_paren)) {

3097 }

3098 }

3099

3101 continue;

3102 }

3103

3104

3105

3106

3109 Tokens.push_back(Tok);

3110

3111

3113 continue;

3114 }

3115

3116 if (Tok.is(tok::hashhash)) {

3117

3118

3119

3120

3121

3123

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

3125 Tokens.push_back(LastTok);

3126 break;

3127 }

3128

3130 Tokens[Tokens.size() - 1].is(tok::comma))

3132

3133

3134 Tokens.push_back(LastTok);

3135 continue;

3136 }

3137

3138

3139

3141

3142

3143 if (!VAOCtx.isVAOptToken(Tok) &&

3146

3147

3148

3149

3150

3152 LastTok.setKind(tok::unknown);

3153 Tokens.push_back(LastTok);

3154 continue;

3155 } else {

3156 Diag(Tok, diag::err_pp_stringize_not_parameter)

3157 << LastTok.is(tok::hashat);

3158 return nullptr;

3159 }

3160 }

3161

3162

3163 Tokens.push_back(LastTok);

3164

3165

3166

3167

3168 if (!VAOCtx.isVAOptToken(Tok)) {

3169 Tokens.push_back(Tok);

3170 LastTok = Tok;

3171

3172

3174 }

3175 }

3176 if (VAOCtx.isInVAOpt()) {

3177 assert(Tok.is(tok::eod) && "Must be at End Of preprocessing Directive");

3178 Diag(Tok, diag::err_pp_expected_after)

3179 << LastTok.getKind() << tok::r_paren;

3180 Diag(VAOCtx.getUnmatchedOpeningParenLoc(), diag::note_matching) << tok::l_paren;

3181 return nullptr;

3182 }

3183 }

3185

3187 return MI;

3188}

3189

3191 return II->isStr("__strong") || II->isStr("__weak") ||

3192 II->isStr("__unsafe_unretained") || II->isStr("__autoreleasing");

3193}

3194

3195

3196

3197void Preprocessor::HandleDefineDirective(

3198 Token &DefineTok, const bool ImmediatelyAfterHeaderGuard) {

3199 ++NumDefined;

3200

3201 Token MacroNameTok;

3202 bool MacroShadowsKeyword;

3203 ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);

3204

3205

3206 if (MacroNameTok.is(tok::eod))

3207 return;

3208

3210

3211

3213 emitFinalMacroWarning(MacroNameTok, false);

3214

3215

3216

3217 if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);

3218

3219 MacroInfo *const MI = ReadOptionalMacroParameterListAndBody(

3220 MacroNameTok, ImmediatelyAfterHeaderGuard);

3221

3222 if (!MI) return;

3223

3224 if (MacroShadowsKeyword &&

3226 Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);

3227 }

3228

3229

3231 if (NumTokens != 0) {

3234 return;

3235 }

3238 return;

3239 }

3240 }

3241

3242

3243 if (SkippingUntilPCHThroughHeader) {

3245 if (!OtherMI || !MI->isIdenticalTo(*OtherMI, *this,

3246 LangOpts.MicrosoftExt))

3249

3250 if (!LangOpts.MicrosoftExt)

3251 return;

3252 }

3253

3254

3255

3257

3258

3259

3261 emitFinalMacroWarning(MacroNameTok, false);

3262

3263

3264

3265

3270

3271 if ((getDiagnostics().getSuppressSystemWarnings() ||

3272 !SourceMgr.isInSystemHeader(DefineTok.getLocation())) &&

3274 LangOpts.MicrosoftExt)) {

3276 }

3278 return;

3279 }

3280

3281

3282

3283

3284 if (getDiagnostics().getSuppressSystemWarnings() ||

3285 !SourceMgr.isInSystemHeader(DefineTok.getLocation())) {

3286

3289

3290

3291

3293 Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);

3294

3295

3297 !MI->isIdenticalTo(*OtherMI, *this, LangOpts.MicrosoftExt)) {

3301 }

3302 }

3305 }

3306

3307 DefMacroDirective *MD =

3309

3310 assert(!MI->isUsed());

3311

3312

3314 !Diags->isIgnored(diag::pp_macro_not_used, MI->getDefinitionLoc()) &&

3315 !MacroExpansionInDirectivesOverride &&

3320 }

3321

3322

3323 if (Callbacks)

3324 Callbacks->MacroDefined(MacroNameTok, MD);

3325}

3326

3327

3328

3329void Preprocessor::HandleUndefDirective() {

3330 ++NumUndefined;

3331

3332 Token MacroNameTok;

3333 ReadMacroName(MacroNameTok, MU_Undef);

3334

3335

3336 if (MacroNameTok.is(tok::eod))

3337 return;

3338

3339

3341

3342

3345 UndefMacroDirective *Undef = nullptr;

3346

3348 emitFinalMacroWarning(MacroNameTok, true);

3349

3350

3351 if (const MacroInfo *MI = MD.getMacroInfo()) {

3354

3355

3356

3358 Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);

3359

3362

3363 Undef = AllocateUndefMacroDirective(MacroNameTok.getLocation());

3364 }

3365

3366

3367

3368 if (Callbacks)

3369 Callbacks->MacroUndefined(MacroNameTok, MD, Undef);

3370

3371 if (Undef)

3373}

3374

3375

3376

3377

3378

3379

3380

3381

3382

3383

3384void Preprocessor::HandleIfdefDirective(Token &Result,

3385 const Token &HashToken,

3386 bool isIfndef,

3387 bool ReadAnyTokensBeforeDirective) {

3388 ++NumIf;

3389 Token DirectiveTok = Result;

3390

3391 Token MacroNameTok;

3392 ReadMacroName(MacroNameTok);

3393

3394

3395 if (MacroNameTok.is(tok::eod)) {

3396

3397

3398 SkipExcludedConditionalBlock(HashToken.getLocation(),

3400 false, false);

3401 return;

3402 }

3403

3405

3406

3408

3412

3413 if (CurPPLexer->getConditionalStackDepth() == 0) {

3414

3415

3416

3417

3418 if (!ReadAnyTokensBeforeDirective && !MI) {

3419 assert(isIfndef && "#ifdef shouldn't reach here");

3420 CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.getLocation());

3421 } else

3422 CurPPLexer->MIOpt.EnterTopLevelConditional();

3423 }

3424

3425

3426 if (MI)

3428

3429 if (Callbacks) {

3430 if (isIfndef)

3431 Callbacks->Ifndef(DirectiveTok.getLocation(), MacroNameTok, MD);

3432 else

3433 Callbacks->Ifdef(DirectiveTok.getLocation(), MacroNameTok, MD);

3434 }

3435

3436 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&

3438

3439

3440 if (PPOpts.SingleFileParseMode && !MI) {

3441

3442

3443 CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),

3444 false, false,

3445 false);

3446 } else if (!MI == isIfndef || RetainExcludedCB) {

3447

3448 CurPPLexer->pushConditionalLevel(DirectiveTok.getLocation(),

3449 false, true,

3450 false);

3451 } else {

3452

3453 SkipExcludedConditionalBlock(HashToken.getLocation(),

3455 false,

3456 false);

3457 }

3458}

3459

3460

3461

3462void Preprocessor::HandleIfDirective(Token &IfToken,

3463 const Token &HashToken,

3464 bool ReadAnyTokensBeforeDirective) {

3465 ++NumIf;

3466

3467

3468 IdentifierInfo *IfNDefMacro = nullptr;

3469 const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);

3470 const bool ConditionalTrue = DER.Conditional;

3471

3472

3473 if (!CurPPLexer)

3474 return;

3475

3476

3477

3478 if (CurPPLexer->getConditionalStackDepth() == 0) {

3479 if (!ReadAnyTokensBeforeDirective && IfNDefMacro && ConditionalTrue)

3480

3481 CurPPLexer->MIOpt.EnterTopLevelIfndef(IfNDefMacro, IfToken.getLocation());

3482 else

3483 CurPPLexer->MIOpt.EnterTopLevelConditional();

3484 }

3485

3486 if (Callbacks)

3487 Callbacks->If(

3490

3491 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&

3493

3494

3495 if (PPOpts.SingleFileParseMode && DER.IncludedUndefinedIds) {

3496

3497

3498 CurPPLexer->pushConditionalLevel(IfToken.getLocation(), false,

3499 false, false);

3500 } else if (ConditionalTrue || RetainExcludedCB) {

3501

3502 CurPPLexer->pushConditionalLevel(IfToken.getLocation(), false,

3503 true, false);

3504 } else {

3505

3507 false,

3508 false);

3509 }

3510}

3511

3512

3513

3514void Preprocessor::HandleEndifDirective(Token &EndifToken) {

3515 ++NumEndif;

3516

3517

3519

3520 PPConditionalInfo CondInfo;

3521 if (CurPPLexer->popConditionalLevel(CondInfo)) {

3522

3523 Diag(EndifToken, diag::err_pp_endif_without_if);

3524 return;

3525 }

3526

3527

3528 if (CurPPLexer->getConditionalStackDepth() == 0)

3529 CurPPLexer->MIOpt.ExitTopLevelConditional();

3530

3531 assert(!CondInfo.WasSkipping && !CurPPLexer->LexingRawMode &&

3532 "This code should only be reachable in the non-skipping case!");

3533

3534 if (Callbacks)

3536}

3537

3538

3539

3540void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) {

3541 ++NumElse;

3542

3543

3545

3546 PPConditionalInfo CI;

3547 if (CurPPLexer->popConditionalLevel(CI)) {

3548 Diag(Result, diag::pp_err_else_without_if);

3549 return;

3550 }

3551

3552

3553 if (CurPPLexer->getConditionalStackDepth() == 0)

3554 CurPPLexer->MIOpt.EnterTopLevelConditional();

3555

3556

3558

3559 if (Callbacks)

3560 Callbacks->Else(Result.getLocation(), CI.IfLoc);

3561

3562 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&

3564

3565 if ((PPOpts.SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {

3566

3567

3568 CurPPLexer->pushConditionalLevel(CI.IfLoc, false,

3569 false, true);

3570 return;

3571 }

3572

3573

3574 SkipExcludedConditionalBlock(HashToken.getLocation(), CI.IfLoc,

3575 true,

3576 true, Result.getLocation());

3577}

3578

3579

3580void Preprocessor::HandleElifFamilyDirective(Token &ElifToken,

3581 const Token &HashToken,

3586 ++NumElse;

3587

3588

3589 switch (DirKind) {

3592 unsigned DiagID;

3593 if (LangOpts.CPlusPlus)

3594 DiagID = LangOpts.CPlusPlus23 ? diag::warn_cxx23_compat_pp_directive

3595 : diag::ext_cxx23_pp_directive;

3596 else

3597 DiagID = LangOpts.C23 ? diag::warn_c23_compat_pp_directive

3598 : diag::ext_c23_pp_directive;

3599 Diag(ElifToken, DiagID) << DirKind;

3600 break;

3601 default:

3602 break;

3603 }

3604

3605

3606

3607

3609

3610 PPConditionalInfo CI;

3611 if (CurPPLexer->popConditionalLevel(CI)) {

3612 Diag(ElifToken, diag::pp_err_elif_without_if) << DirKind;

3613 return;

3614 }

3615

3616

3617 if (CurPPLexer->getConditionalStackDepth() == 0)

3618 CurPPLexer->MIOpt.EnterTopLevelConditional();

3619

3620

3622 Diag(ElifToken, diag::pp_err_elif_after_else) << DirKind;

3623

3624 if (Callbacks) {

3625 switch (Kind) {

3626 case tok::pp_elif:

3627 Callbacks->Elif(ElifToken.getLocation(), ConditionRange,

3629 break;

3630 case tok::pp_elifdef:

3631 Callbacks->Elifdef(ElifToken.getLocation(), ConditionRange, CI.IfLoc);

3632 break;

3633 case tok::pp_elifndef:

3634 Callbacks->Elifndef(ElifToken.getLocation(), ConditionRange, CI.IfLoc);

3635 break;

3636 default:

3637 assert(false && "unexpected directive kind");

3638 break;

3639 }

3640 }

3641

3642 bool RetainExcludedCB = PPOpts.RetainExcludedConditionalBlocks &&

3644

3645 if ((PPOpts.SingleFileParseMode && !CI.FoundNonSkip) || RetainExcludedCB) {

3646

3647

3648 CurPPLexer->pushConditionalLevel(ElifToken.getLocation(), false,

3649 false, false);

3650 return;

3651 }

3652

3653

3654 SkipExcludedConditionalBlock(

3657}

3658

3659std::optional

3662 tok::TokenKind EndTokenKind = ForHasEmbed ? tok::r_paren : tok::eod;

3663

3664 auto DiagMismatchedBracesAndSkipToEOD =

3666 std::pair<tok::TokenKind, SourceLocation> Matches) {

3667 Diag(CurTok, diag::err_expected) << Expected;

3668 Diag(Matches.second, diag::note_matching) << Matches.first;

3669 if (CurTok.isNot(EndTokenKind))

3671 };

3672

3673 auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) {

3674 if (CurTok.isNot(Kind)) {

3675 Diag(CurTok, diag::err_expected) << Kind;

3676 if (CurTok.isNot(EndTokenKind))

3678 return false;

3679 }

3680 return true;

3681 };

3682

3683

3684

3685

3686

3687

3688

3689

3690

3691

3692

3693 auto LexPPParameterName = [&]() -> std::optionalstd::string {

3694

3695

3696 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))

3697 return std::nullopt;

3698

3700

3701

3702

3704 if (CurTok.is(tok::coloncolon)) {

3705

3707 if (!ExpectOrDiagAndSkipToEOD(tok::identifier))

3708 return std::nullopt;

3709

3711

3712

3714 return (llvm::Twine(Prefix->getName()) + "::" + Suffix->getName()).str();

3715 }

3716 return Prefix->getName().str();

3717 };

3718

3719

3720

3721

3722

3723 auto NormalizeParameterName = [](StringRef Name) {

3724 if (Name.size() > 4 && Name.starts_with("__") && Name.ends_with("__"))

3725 return Name.substr(2, Name.size() - 4);

3726 return Name;

3727 };

3728

3729 auto LexParenthesizedIntegerExpr = [&]() -> std::optional<size_t> {

3730

3731

3732 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))

3733 return std::nullopt;

3734

3735

3736

3738 bool EvaluatedDefined;

3739 DirectiveEvalResult LimitEvalResult = EvaluateDirectiveExpression(

3740 ParameterIfNDef, CurTok, EvaluatedDefined, false);

3741

3742 if (!LimitEvalResult.Value) {

3743

3744

3745 assert(CurTok.is(tok::eod) && "expect to be at the end of directive");

3746 return std::nullopt;

3747 }

3748

3749 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))

3750 return std::nullopt;

3751

3752

3754

3755

3756

3757 if (EvaluatedDefined) {

3758 Diag(CurTok, diag::err_defined_in_pp_embed);

3759 return std::nullopt;

3760 }

3761

3762 if (LimitEvalResult.Value) {

3763 const llvm::APSInt &Result = *LimitEvalResult.Value;

3764 if (Result.isNegative()) {

3765 Diag(CurTok, diag::err_requires_positive_value)

3767 if (CurTok.isNot(EndTokenKind))

3769 return std::nullopt;

3770 }

3771 return Result.getLimitedValue();

3772 }

3773 return std::nullopt;

3774 };

3775

3776 auto GetMatchingCloseBracket = [](tok::TokenKind Kind) {

3777 switch (Kind) {

3778 case tok::l_paren:

3779 return tok::r_paren;

3780 case tok::l_brace:

3781 return tok::r_brace;

3782 case tok::l_square:

3783 return tok::r_square;

3784 default:

3785 llvm_unreachable("should not get here");

3786 }

3787 };

3788

3789 auto LexParenthesizedBalancedTokenSoup =

3791 std::vector<std::pair<tok::TokenKind, SourceLocation>> BracketStack;

3792

3793

3794 if (!ExpectOrDiagAndSkipToEOD(tok::l_paren))

3795 return false;

3797

3798 bool WaitingForInnerCloseParen = false;

3799 while (CurTok.isNot(tok::eod) &&

3800 (WaitingForInnerCloseParen || CurTok.isNot(tok::r_paren))) {

3801 switch (CurTok.getKind()) {

3802 default:

3803 break;

3804 case tok::l_paren:

3805 WaitingForInnerCloseParen = true;

3806 [[fallthrough]];

3807 case tok::l_brace:

3808 case tok::l_square:

3810 break;

3811 case tok::r_paren:

3812 WaitingForInnerCloseParen = false;

3813 [[fallthrough]];

3814 case tok::r_brace:

3815 case tok::r_square: {

3816 if (BracketStack.empty()) {

3817 ExpectOrDiagAndSkipToEOD(tok::r_paren);

3818 return false;

3819 }

3821 GetMatchingCloseBracket(BracketStack.back().first);

3822 if (CurTok.getKind() != Matching) {

3823 DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back());

3824 return false;

3825 }

3826 BracketStack.pop_back();

3827 } break;

3828 }

3829 Tokens.push_back(CurTok);

3831 }

3832

3833

3834 if (!ExpectOrDiagAndSkipToEOD(tok::r_paren))

3835 return false;

3836

3838 return true;

3839 };

3840

3842 while (!CurTok.isOneOf(EndTokenKind, tok::eod)) {

3844 std::optionalstd::string ParamName = LexPPParameterName();

3845 if (!ParamName)

3846 return std::nullopt;

3847 StringRef Parameter = NormalizeParameterName(*ParamName);

3848

3849

3850

3851

3852

3854 if (Result.MaybeLimitParam)

3855 Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;

3856

3857 std::optional<size_t> Limit = LexParenthesizedIntegerExpr();

3858 if (!Limit)

3859 return std::nullopt;

3860 Result.MaybeLimitParam =

3862 } else if (Parameter == "clang::offset") {

3863 if (Result.MaybeOffsetParam)

3864 Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;

3865

3866 std::optional<size_t> Offset = LexParenthesizedIntegerExpr();

3867 if (!Offset)

3868 return std::nullopt;

3870 *Offset, {ParamStartLoc, CurTok.getLocation()}};

3871 } else if (Parameter == "prefix") {

3872 if (Result.MaybePrefixParam)

3873 Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;

3874

3876 if (!LexParenthesizedBalancedTokenSoup(Soup))

3877 return std::nullopt;

3879 std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};

3880 } else if (Parameter == "suffix") {

3881 if (Result.MaybeSuffixParam)

3882 Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;

3883

3885 if (!LexParenthesizedBalancedTokenSoup(Soup))

3886 return std::nullopt;

3888 std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};

3889 } else if (Parameter == "if_empty") {

3890 if (Result.MaybeIfEmptyParam)

3891 Diag(CurTok, diag::err_pp_embed_dup_params) << Parameter;

3892

3894 if (!LexParenthesizedBalancedTokenSoup(Soup))

3895 return std::nullopt;

3897 std::move(Soup), {ParamStartLoc, CurTok.getLocation()}};

3898 } else {

3899 ++Result.UnrecognizedParams;

3900

3901

3902

3903 if (CurTok.is(tok::l_paren)) {

3905 if (!LexParenthesizedBalancedTokenSoup(Soup))

3906 return std::nullopt;

3907 }

3908 if (!ForHasEmbed) {

3909 Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter;

3910 if (CurTok.isNot(EndTokenKind))

3912 return std::nullopt;

3913 }

3914 }

3915 }

3917}

3918

3919void Preprocessor::HandleEmbedDirectiveImpl(

3921 StringRef BinaryContents, StringRef FileName) {

3922 if (BinaryContents.empty()) {

3923

3924

3925

3926

3927

3930 size_t TokCount = Toks.size();

3931 auto NewToks = std::make_unique<Token[]>(TokCount);

3932 llvm::copy(Toks, NewToks.get());

3933 EnterTokenStream(std::move(NewToks), TokCount, true, true);

3934 }

3935 return;

3936 }

3937

3940 size_t TotalNumToks = 1 + NumPrefixToks + NumSuffixToks;

3941 size_t CurIdx = 0;

3942 auto Toks = std::make_unique<Token[]>(TotalNumToks);

3943

3944

3947 CurIdx += NumPrefixToks;

3948 }

3949

3950 EmbedAnnotationData *Data = new (BP) EmbedAnnotationData;

3951 Data->BinaryData = BinaryContents;

3953

3954 Toks[CurIdx].startToken();

3955 Toks[CurIdx].setKind(tok::annot_embed);

3956 Toks[CurIdx].setAnnotationRange(HashLoc);

3957 Toks[CurIdx++].setAnnotationValue(Data);

3958

3959

3962 CurIdx += NumSuffixToks;

3963 }

3964

3965 assert(CurIdx == TotalNumToks && "Calculated the incorrect number of tokens");

3966 EnterTokenStream(std::move(Toks), TotalNumToks, true, true);

3967}

3968

3969void Preprocessor::HandleEmbedDirective(SourceLocation HashLoc, Token &EmbedTok,

3970 const FileEntry *LookupFromFile) {

3971

3972 if (LangOpts.C23)

3973 Diag(EmbedTok, diag::warn_compat_pp_embed_directive);

3974 else

3975 Diag(EmbedTok, diag::ext_pp_embed_directive)

3976 << (LangOpts.CPlusPlus ? 1 : 0);

3977

3978

3979 Token FilenameTok;

3981 return;

3982

3983 if (FilenameTok.isNot(tok::header_name)) {

3984 Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);

3985 if (FilenameTok.isNot(tok::eod))

3987 return;

3988 }

3989

3990

3991

3992

3993

3994

3995

3996

3997 Token CurTok;

3998 std::optional Params =

4000

4001 assert((Params || CurTok.is(tok::eod)) &&

4002 "expected success or to be at the end of the directive");

4003 if (!Params)

4004 return;

4005

4006

4007 SmallString<128> FilenameBuffer;

4008 StringRef Filename = getSpelling(FilenameTok, FilenameBuffer);

4009 StringRef OriginalFilename = Filename;

4010 bool isAngled =

4012

4013

4014

4015 if (Filename.empty())

4016 return;

4017

4019 this->LookupEmbedFile(Filename, isAngled, true, LookupFromFile);

4020 if (!MaybeFileRef) {

4021

4022 if (Callbacks && Callbacks->EmbedFileNotFound(Filename)) {

4023 return;

4024 }

4025 Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;

4026 return;

4027 }

4028

4030 Diag(FilenameTok, diag::err_pp_embed_device_file) << Filename;

4031 return;

4032 }

4033

4034 std::optionalllvm::MemoryBufferRef MaybeFile =

4036 if (!MaybeFile) {

4037

4038 Diag(FilenameTok, diag::err_cannot_open_file)

4039 << Filename << "a buffer to the contents could not be created";

4040 return;

4041 }

4042 StringRef BinaryContents = MaybeFile->getBuffer();

4043

4044

4045

4046

4047 if (Params->MaybeOffsetParam) {

4048

4049

4050

4051

4052 BinaryContents = BinaryContents.substr(Params->MaybeOffsetParam->Offset);

4053 }

4054

4055 if (Params->MaybeLimitParam) {

4056

4057

4058

4059 BinaryContents = BinaryContents.substr(0, Params->MaybeLimitParam->Limit);

4060 }

4061

4062 if (Callbacks)

4063 Callbacks->EmbedDirective(HashLoc, Filename, isAngled, MaybeFileRef,

4064 *Params);

4065

4066

4067

4068

4069

4070

4071

4072 void *Mem = BP.Allocate(OriginalFilename.size(), alignof(char *));

4073 memcpy(Mem, OriginalFilename.data(), OriginalFilename.size());

4074 StringRef FilenameToGo =

4075 StringRef(static_cast<char *>(Mem), OriginalFilename.size());

4076 HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);

4077}

static bool isInMainFile(const clang::Diagnostic &D)

Defines interfaces for clang::DirectoryEntry and clang::DirectoryEntryRef.

Defines the clang::FileManager interface and associated types.

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

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 ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, SrcMgr::CharacteristicKind &FileKind, Preprocessor &PP)

ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line marker directive.

Definition PPDirectives.cpp:1597

static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI, const LangOptions &LOptions)

Definition PPDirectives.cpp:2909

static void diagnoseAutoModuleImport(Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok, ArrayRef< IdentifierLoc > Path, SourceLocation PathEnd)

Produce a diagnostic informing the user that a include or similar was implicitly treated as a module ...

Definition PPDirectives.cpp:1940

static std::optional< StringRef > findSimilarStr(StringRef LHS, const std::vector< StringRef > &Candidates)

Find a similar string in Candidates.

Definition PPDirectives.cpp:323

static bool isLanguageDefinedBuiltin(const SourceManager &SourceMgr, const MacroInfo *MI, const StringRef MacroName)

Definition PPDirectives.cpp:154

static bool trySimplifyPath(SmallVectorImpl< StringRef > &Components, StringRef RealPathName, llvm::sys::path::Style Separator)

Definition PPDirectives.cpp:1980

static bool warnByDefaultOnWrongCase(StringRef Include)

Definition PPDirectives.cpp:223

MacroDiag

Enumerates possible cases of define/undef a reserved identifier.

Definition PPDirectives.cpp:99

@ MD_ReservedMacro

Definition PPDirectives.cpp:102

@ MD_ReservedAttributeIdentifier

Definition PPDirectives.cpp:103

@ MD_NoWarn

Definition PPDirectives.cpp:100

@ MD_KeywordDef

Definition PPDirectives.cpp:101

static bool isFeatureTestMacro(StringRef MacroName)

Definition PPDirectives.cpp:114

static bool GetLineValue(Token &DigitTok, unsigned &Val, unsigned DiagID, Preprocessor &PP, bool IsGNULineDirective=false)

GetLineValue - Convert a numeric token into an unsigned value, emitting Diagnostic DiagID if it is in...

Definition PPDirectives.cpp:1460

PPElifDiag

Enumerates possible select values for the pp_err_elif_after_else and pp_err_elif_without_if diagnosti...

Definition PPDirectives.cpp:108

@ PED_Elifndef

Definition PPDirectives.cpp:111

@ PED_Elifdef

Definition PPDirectives.cpp:110

@ PED_Elif

Definition PPDirectives.cpp:109

static bool isReservedCXXAttributeName(Preprocessor &PP, IdentifierInfo *II)

Definition PPDirectives.cpp:178

static MacroDiag shouldWarnOnMacroUndef(Preprocessor &PP, IdentifierInfo *II)

Definition PPDirectives.cpp:208

static bool isObjCProtectedMacro(const IdentifierInfo *II)

Definition PPDirectives.cpp:3190

static MacroDiag shouldWarnOnMacroDef(Preprocessor &PP, IdentifierInfo *II)

Definition PPDirectives.cpp:194

Defines the clang::Preprocessor interface.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

Defines the clang::SourceLocation class and associated facilities.

static bool isInvalid(LocType Loc, bool *Invalid)

Defines the SourceManager interface.

Defines the clang::TokenKind enum and support functions.

VerifyDiagnosticConsumer::Directive Directive

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

__device__ __2f16 float c

Definition PPDirectives.cpp:1194

ResetMacroExpansionHelper(Preprocessor *pp)

Definition PPDirectives.cpp:1196

~ResetMacroExpansionHelper()

Definition PPDirectives.cpp:1202

static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name)

Represents a character-granular source range.

static CharSourceRange getCharRange(SourceRange R)

virtual void CodeCompleteMacroName(bool IsDefinition)

Callback invoked when performing code completion in a context where the name of a macro is expected.

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

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

A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...

StringRef getName() const

bool isDeviceFile() const

const FileEntry & getFileEntry() const

DirectoryEntryRef getDir() const

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

StringRef tryGetRealPathName() const

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::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)

Lookup, cache, and verify the specified directory (real or virtual).

llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)

Lookup, cache, and verify the specified file (real or virtual).

Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

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

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

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

tok::PPKeywordKind getPPKeywordID() const

Return the preprocessor keyword ID for this identifier.

bool isCPlusPlusOperatorKeyword() const

bool hadMacroDefinition() const

Returns true if this identifier was #defined to some value at any moment.

bool hasMacroDefinition() const

Return true if this identifier is #defined to some other value.

const char * getNameStart() const

Return the beginning of the actual null-terminated string for this identifier.

bool isKeyword(const LangOptions &LangOpts) const

Return true if this token is a keyword in the specified language.

ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const

Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

StringRef getName() const

Return the actual identifier string.

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

bool IsHeaderFile

Indicates whether the front-end is explicitly told that the input is a header file (i....

std::string CurrentModule

The name of the current module, of which the main source file is a part.

const MacroInfo * getMacroInfo() const

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

bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, bool Syntactically) const

Return true if the specified macro definition is equal to this macro in spelling, arguments,...

bool isUsed() const

Return false if this macro is defined in the main file and has not yet been used.

bool isC99Varargs() const

bool isAllowRedefinitionsWithoutWarning() const

Return true if this macro can be redefined without warning.

void setHasCommaPasting()

unsigned getNumTokens() const

Return the number of tokens that this macro expands to.

const Token & getReplacementToken(unsigned Tok) const

void setDefinitionEndLoc(SourceLocation EndLoc)

Set the location of the last token in the macro.

bool isBuiltinMacro() const

Return true if this macro requires processing before expansion.

void setTokens(ArrayRef< Token > Tokens, llvm::BumpPtrAllocator &PPAllocator)

void setParameterList(ArrayRef< IdentifierInfo * > List, llvm::BumpPtrAllocator &PPAllocator)

Set the specified list of identifiers as the parameter list for this macro.

SourceLocation getDefinitionLoc() const

Return the location that the macro was defined at.

void setIsFunctionLike()

Function/Object-likeness.

bool isObjectLike() const

void setIsWarnIfUnused(bool val)

Set the value of the IsWarnIfUnused flag.

int getParameterNum(const IdentifierInfo *Arg) const

Return the parameter number of the specified identifier, or -1 if the identifier is not a formal para...

bool isWarnIfUnused() const

Return true if we should emit a warning if the macro is unused.

void setIsC99Varargs()

Varargs querying methods. This can only be set for function-like macros.

bool isMissingExpected() const

Determines whether the module, which failed to load, was actually a submodule that we expected to see...

bool isConfigMismatch() const

Determines whether the module failed to load due to a configuration mismatch with an explicitly-named...

@ ExcludedHeader

This header is explicitly excluded from the module.

@ TextualHeader

This header is part of the module (for layering purposes) but should be textually included.

Describes a module or submodule.

StringRef getTopLevelModuleName() const

Retrieve the name of the top-level module.

bool isForBuilding(const LangOptions &LangOpts) const

Determine whether this module can be built in this compilation.

@ Hidden

All of the names in this module are hidden.

SourceLocation DefinitionLoc

The location of the module definition.

unsigned IsSystem

Whether this is a "system" module (which assumes that all headers in it are system headers).

std::string Name

The name of this module.

bool isAvailable() const

Determine whether this module is available for use within the current translation unit.

bool isHeaderUnit() const

Is this module a header unit.

Module * ShadowingModule

A module with the same name that shadows this module.

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

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

Module * getTopLevelModule()

Retrieve the top-level module for this (sub)module, which may be this module.

Preprocessor standard embed parameter "if_empty" if_empty( balanced-token-seq )

Preprocessor standard embed parameter "limit" limit( constant-expression )

Preprocessor extension embed parameter "clang::offset" clang::offset( constant-expression )

Preprocessor standard embed parameter "prefix" prefix( balanced-token-seq )

Preprocessor standard embed parameter "suffix" suffix( balanced-token-seq )

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

MacroDirective * getLocalMacroDirective(const IdentifierInfo *II) const

Given an identifier, return its latest non-imported MacroDirective if it is #define'd and not #undef'...

void markClangModuleAsAffecting(Module *M)

Mark the given clang module as affecting the current clang module or translation unit.

OptionalFileEntryRef LookupEmbedFile(StringRef Filename, bool isAngled, bool OpenFile, const FileEntry *LookupFromFile=nullptr)

Given a "Filename" or reference, look up the indicated embed resource.

Definition PPDirectives.cpp:1121

const MacroInfo * getMacroInfo(const IdentifierInfo *II) const

bool isRecordingPreamble() const

void HandleSkippedDirectiveWhileUsingPCH(Token &Result, SourceLocation HashLoc)

Process directives while skipping until the through header or pragma hdrstop is found.

Definition PPDirectives.cpp:1217

bool isInPrimaryFile() const

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

void markMacroAsUsed(MacroInfo *MI)

A macro is used, update information about macros that need unused warnings.

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

void setCodeCompletionReached()

Note that we hit the code-completion point.

StringRef getNamedModuleName() const

Get the named module name we're preprocessing.

void Lex(Token &Result)

Lex the next token for this preprocessor.

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 LexNonComment(Token &Result)

Lex a token.

SourceRange DiscardUntilEndOfDirective()

Read and discard all tokens remaining on the current line until the tok::eod token is found.

SourceLocation CheckEndOfDirective(const char *DirType, bool EnableMacros=false)

Ensure that the next token is a tok::eod token.

Definition PPDirectives.cpp:459

friend class VAOptDefinitionContext

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

SourceManager & getSourceManager() const

MacroDefinition getMacroDefinition(const IdentifierInfo *II)

bool CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef, bool *ShadowFlag=nullptr)

Definition PPDirectives.cpp:359

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.

Definition PPDirectives.cpp:2019

SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Char) const

Given a location that specifies the start of a token, return a new location that specifies a characte...

bool isNextPPTokenOneOf(Ts... Ks)

Check whether the next pp-token is one of the specificed token kind.

Module * getCurrentModule()

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

void makeModuleVisible(Module *M, SourceLocation Loc, bool IncludeExports=true)

bool hadModuleLoaderFatalFailure() const

const TargetInfo & getTargetInfo() const

FileManager & getFileManager() 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.

friend class VariadicMacroScopeGuard

MacroInfo * AllocateMacroInfo(SourceLocation L)

Allocate a new MacroInfo object with the provided SourceLocation.

Definition PPDirectives.cpp:62

void LexUnexpandedToken(Token &Result)

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

bool alreadyIncluded(FileEntryRef File) const

Return true if this header has already been included.

FileID getPredefinesFileID() const

Returns the FileID for the preprocessor predefines.

void LexUnexpandedNonComment(Token &Result)

Like LexNonComment, but this disables macro expansion of identifier tokens.

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.

Definition PPDirectives.cpp:1876

PreprocessorLexer * getCurrentFileLexer() const

Return the current file lexer being lexed from.

HeaderSearch & getHeaderSearchInfo() const

void emitMacroExpansionWarnings(const Token &Identifier, bool IsIfnDef=false) const

void HandleDirective(Token &Result)

Callback invoked when the lexer sees a # token at the start of a line.

Definition PPDirectives.cpp:1242

void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal)

Enter an annotation token into the token stream.

Definition PPDirectives.cpp:1924

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.

Definition PPDirectives.cpp:995

const LangOptions & getLangOpts() const

bool isInNamedModule() const

If we are preprocessing a named module.

OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, SourceLocation MLoc)

We want to produce a diagnostic at location IncLoc concerning an unreachable effect at location MLoc ...

Definition PPDirectives.cpp:925

DefMacroDirective * appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)

void HandlePragmaHdrstop(Token &Tok)

DiagnosticsEngine & getDiagnostics() const

std::optional< LexEmbedParametersResult > LexEmbedParameters(Token &Current, bool ForHasEmbed)

Lex the parameters for an embed directive, returns nullopt on error.

Definition PPDirectives.cpp:3660

Module * getModuleForLocation(SourceLocation Loc, bool AllowTextual)

Find the module that owns the source or header file that Loc points to.

Definition PPDirectives.cpp:903

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

bool usingPCHWithThroughHeader()

True if using a PCH with a through header.

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

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.

bool isInvalid() const

Return true if this object is invalid or uninitialized.

SourceLocation getIncludeLoc() const

Return the presumed include location of this location.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

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

bool isInMainFile(SourceLocation Loc) const

Returns whether the PresumedLoc for a given SourceLocation is in the main file.

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.

void setBegin(SourceLocation b)

SourceLocation getEnd() const

void setEnd(SourceLocation e)

Exposes information about the current target.

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

IdentifierInfo * getIdentifierInfo() const

SourceLocation getEndLoc() const

void clearFlag(TokenFlags Flag)

Unset the specified flag.

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 isOneOf(Ts... Ks) const

bool hasLeadingSpace() const

Return true if this token has whitespace before it.

bool isNot(tok::TokenKind K) const

bool hasUDSuffix() const

Return true if this token is a string or character literal which has a ud-suffix.

bool needsCleaning() const

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

StringRef getRawIdentifier() const

getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode),...

A directive for an undefined macro.

A directive for setting the module visibility of a macro.

Defines the clang::TargetInfo interface.

CharacteristicKind

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

uint32_t Literal

Literals are represented as positive integers.

bool Sub(InterpState &S, CodePtr OpPC)

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

PPKeywordKind

Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.

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

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

bool isReservedInAllContexts(ReservedIdentifierStatus Status)

Determine whether an identifier is reserved in all contexts.

int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)

Return the version number associated with the attribute if we recognize and implement the attribute s...

LLVM_READONLY char toLowercase(char c)

Converts the given ASCII character to its lowercase equivalent.

detail::SearchDirIteratorImpl< true > ConstSearchDirIterator

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

MacroUse

Context in which macro name is used.

LLVM_READONLY bool isAlphanumeric(unsigned char c)

Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].

@ Module

Module linkage, which indicates that the entity can be referred to from other translation units withi...

@ Parameter

The parameter type of a method or function.

@ Result

The result type of a method or function.

LLVM_READONLY bool isDigit(unsigned char c)

Return true if this character is an ASCII digit: [0-9].

LLVM_READONLY bool isLowercase(unsigned char c)

Return true if this character is a lowercase ASCII letter: [a-z].

@ PIK_HashPragma

The pragma was introduced via #pragma.

OptionalDirectoryEntryRef Directory

The directory entry which should be used for the cached framework.

std::optional< PPEmbedParameterIfEmpty > MaybeIfEmptyParam

size_t SuffixTokenCount() const

std::optional< PPEmbedParameterSuffix > MaybeSuffixParam

std::optional< PPEmbedParameterPrefix > MaybePrefixParam

size_t PrefixTokenCount() const

bool FoundNonSkip

True if we have emitted tokens already, and now we're in an #else block or something.

SourceLocation IfLoc

Location where the conditional started.

bool WasSkipping

True if this was contained in a skipping directive, e.g., in a "\#if 0" block.

bool FoundElse

True if we've seen a #else in this block.