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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

31#include "llvm/ADT/APSInt.h"

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

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

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

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

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

37#include

38

39using namespace clang;

40

41namespace {

42

43

44

45class PPValue {

46 SourceRange Range;

47 IdentifierInfo *II = nullptr;

48

49public:

50 llvm::APSInt Val;

51

52

53 PPValue(unsigned BitWidth) : Val(BitWidth) {}

54

55

56

57 IdentifierInfo *getIdentifier() const { return II; }

58 void setIdentifier(IdentifierInfo *II) { this->II = II; }

59

60 unsigned getBitWidth() const { return Val.getBitWidth(); }

61 bool isUnsigned() const { return Val.isUnsigned(); }

62

63 SourceRange getRange() const { return Range; }

64

65 void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }

66 void setRange(SourceLocation B, SourceLocation E) {

67 Range.setBegin(B); Range.setEnd(E);

68 }

69 void setBegin(SourceLocation L) { Range.setBegin(L); }

70 void setEnd(SourceLocation L) { Range.setEnd(L); }

71};

72

73}

74

76 Token &PeekTok, bool ValueLive,

77 bool &IncludedUndefinedIds,

79

80

81

82

83

84

85

86

100

101

105 Result.setBegin(beginLoc);

106

107

109

110

112 if (PeekTok.is(tok::l_paren)) {

113

116 }

117

118 if (PeekTok.is(tok::code_completion)) {

123 }

124

125

127 return true;

128

129

132 Result.Val = !Macro;

133 Result.Val.setIsUnsigned(false);

135

137 PeekTok,

138 (II->getName() == "INFINITY" || II->getName() == "NAN") ? true : false);

139

140

141 if (Result.Val != 0 && ValueLive)

143

144

145 Token macroToken(PeekTok);

146

147

148 if (LParenLoc.isValid()) {

149

152

153 if (PeekTok.isNot(tok::r_paren)) {

154 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)

155 << "'defined'" << tok::r_paren;

156 PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;

157 return true;

158 }

159

162 } else {

163

166 }

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

187 bool IsFunctionTypeMacro =

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207 if (IsFunctionTypeMacro)

208 PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);

209 else

210 PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);

211 }

212

213

215 Callbacks->Defined(macroToken, Macro,

217 }

218

219

222 return false;

223}

224

225

226

227

228

229

230

231

232

236

237 Result.setIdentifier(nullptr);

238

239 if (PeekTok.is(tok::code_completion)) {

244 }

245

246 switch (PeekTok.getKind()) {

247 default:

248

249

250

252

253 if (II->isStr("defined"))

254 return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);

255

257

258

259

260 if (ValueLive) {

261 unsigned DiagID = II->getName() == "true"

262 ? diag::warn_pp_undef_true_identifier

263 : diag::warn_pp_undef_identifier;

264 PP.Diag(PeekTok, DiagID) << II;

265

267

269 const std::vectorstd::string UndefPrefixes =

271 const StringRef IdentifierName = II->getName();

272 if (llvm::any_of(UndefPrefixes,

273 [&IdentifierName](const std::string &Prefix) {

274 return IdentifierName.starts_with(Prefix);

275 }))

276 PP.Diag(PeekTok, diag::warn_pp_undef_prefix)

277 << AddFlagValue{llvm::join(UndefPrefixes, ",")} << II;

278 }

279 }

280 Result.Val = 0;

281 Result.Val.setIsUnsigned(false);

282 Result.setIdentifier(II);

286 return false;

287 }

288 }

289 PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);

290 return true;

291 case tok::eod:

292 case tok::r_paren:

293

294 PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);

295 return true;

296 case tok::numeric_constant: {

298 bool NumberInvalid = false;

299 StringRef Spelling = PP.getSpelling(PeekTok, IntegerBuffer,

300 &NumberInvalid);

301 if (NumberInvalid)

302 return true;

303

307 if (Literal.hadError)

308 return true;

309

310 if (Literal.isFloatingLiteral() || Literal.isImaginary) {

311 PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);

312 return true;

313 }

314 assert(Literal.isIntegerLiteral() && "Unknown ppnumber");

315

316

317 if (Literal.hasUDSuffix())

318 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 1;

319

320

321 if (!PP.getLangOpts().C99 && Literal.isLongLong) {

323 PP.Diag(PeekTok,

325 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);

326 else

327 PP.Diag(PeekTok, diag::ext_c99_longlong);

328 }

329

330

331 if (Literal.isSizeT)

334 ? diag::warn_cxx20_compat_size_t_suffix

335 : diag::ext_cxx23_size_t_suffix

336 : diag::err_cxx23_size_t_suffix);

337

338

339

340 if (Literal.isBitInt)

341 PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus ? diag::ext_cxx_bitint_suffix

343 ? diag::warn_c23_compat_bitint_suffix

344 : diag::ext_c23_bitint_suffix);

345

346

347 if (Literal.GetIntegerValue(Result.Val)) {

348

349 PP.Diag(PeekTok, diag::err_integer_literal_too_large) << 1;

350 Result.Val.setIsUnsigned(true);

351 } else {

352

353

354 Result.Val.setIsUnsigned(Literal.isUnsigned);

355

356

357

358

359

360 if (!Literal.isUnsigned && Result.Val.isNegative()) {

361

362

363 if (ValueLive && Literal.getRadix() == 10)

364 PP.Diag(PeekTok, diag::ext_integer_literal_too_large_for_signed);

365 Result.Val.setIsUnsigned(true);

366 }

367 }

368

369

372 return false;

373 }

374 case tok::char_constant:

375 case tok::wide_char_constant:

376 case tok::utf8_char_constant:

377 case tok::utf16_char_constant:

378 case tok::utf32_char_constant: {

379

381 PP.Diag(PeekTok, diag::err_pp_invalid_udl) << 0;

382

384 bool CharInvalid = false;

385 StringRef ThisTok = PP.getSpelling(PeekTok, CharBuffer, &CharInvalid);

386 if (CharInvalid)

387 return true;

388

391 if (Literal.hadError())

392 return true;

393

394

396 unsigned NumBits;

397 if (Literal.isMultiChar())

399 else if (Literal.isWide())

401 else if (Literal.isUTF16())

403 else if (Literal.isUTF32())

405 else

407

408

409 llvm::APSInt Val(NumBits);

410

411 Val = Literal.getValue();

412

413

414 if (Literal.isWide())

416 else if (Literal.isUTF16() || Literal.isUTF32())

417 Val.setIsUnsigned(true);

418 else if (Literal.isUTF8()) {

420 Val.setIsUnsigned(

422 else

423 Val.setIsUnsigned(true);

424 } else

425 Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);

426

427 if (Result.Val.getBitWidth() > Val.getBitWidth()) {

428 Result.Val = Val.extend(Result.Val.getBitWidth());

429 } else {

430 assert(Result.Val.getBitWidth() == Val.getBitWidth() &&

431 "intmax_t smaller than char/wchar_t?");

432 Result.Val = Val;

433 }

434

435

438 return false;

439 }

440 case tok::l_paren: {

443

444

445 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;

446

447

448

449 if (PeekTok.is(tok::r_paren)) {

450

451 } else {

452

455 return true;

456

457 if (PeekTok.isNot(tok::r_paren)) {

458 PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)

459 << Result.getRange();

460 PP.Diag(Start, diag::note_matching) << tok::l_paren;

461 return true;

462 }

464 }

465 Result.setRange(Start, PeekTok.getLocation());

466 Result.setIdentifier(nullptr);

468 return false;

469 }

470 case tok:➕ {

472

474 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;

475 Result.setBegin(Start);

476 Result.setIdentifier(nullptr);

477 return false;

478 }

479 case tok:➖ {

482 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;

483 Result.setBegin(Loc);

484 Result.setIdentifier(nullptr);

485

486

487 Result.Val = -Result.Val;

488

489

490 bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();

491

492

493 if (Overflow && ValueLive)

494 PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();

495

497 return false;

498 }

499

500 case tok::tilde: {

503 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;

504 Result.setBegin(Start);

505 Result.setIdentifier(nullptr);

506

507

508 Result.Val = ~Result.Val;

510 return false;

511 }

512

513 case tok::exclaim: {

516 if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;

517 Result.setBegin(Start);

518 Result.Val = !Result.Val;

519

520 Result.Val.setIsUnsigned(false);

521 Result.setIdentifier(nullptr);

522

527 return false;

528 }

529 case tok::kw_true:

530 case tok::kw_false:

531 Result.Val = PeekTok.getKind() == tok::kw_true;

532 Result.Val.setIsUnsigned(false);

536 return false;

537

538

539 }

540}

541

542

543

544

545

546

548 switch (Kind) {

549 default: return ~0U;

550 case tok::percent:

551 case tok::slash:

552 case tok:⭐ return 14;

553 case tok:➕

554 case tok:➖ return 13;

555 case tok::lessless:

556 case tok::greatergreater: return 12;

557 case tok::lessequal:

558 case tok::less:

559 case tok::greaterequal:

560 case tok::greater: return 11;

561 case tok::exclaimequal:

562 case tok::equalequal: return 10;

563 case tok::amp: return 9;

564 case tok::caret: return 8;

565 case tok::pipe: return 7;

566 case tok::ampamp: return 6;

567 case tok::pipepipe: return 5;

568 case tok::question: return 4;

569 case tok::comma: return 3;

570 case tok::colon: return 2;

571 case tok::r_paren: return 0;

572 case tok::eod: return 0;

573 }

574}

575

578 if (Tok.is(tok::l_paren) && LHS.getIdentifier())

579 PP.Diag(LHS.getRange().getBegin(), diag::err_pp_expr_bad_token_lparen)

580 << LHS.getIdentifier();

581 else

582 PP.Diag(Tok.getLocation(), diag::err_pp_expr_bad_token_binop)

583 << LHS.getRange();

584}

585

586

587

588

589

590

591

593 Token &PeekTok, bool ValueLive,

594 bool &IncludedUndefinedIds,

598 IncludedUndefinedIds) {

599

600

601

602

604 return true;

605 }

606

608

609 if (PeekPrec == ~0U) {

611 return true;

612 }

613

614 while (true) {

615

616

617 if (PeekPrec < MinPrec)

618 return false;

619

621

622

623

624

625

626

627 bool RHSIsLive;

628 if (Operator == tok::ampamp && LHS.Val == 0)

629 RHSIsLive = false;

630 else if (Operator == tok::pipepipe && LHS.Val != 0)

631 RHSIsLive = false;

632 else if (Operator == tok::question && LHS.Val == 0)

633 RHSIsLive = false;

634 else

635 RHSIsLive = ValueLive;

636

637

640

641 PPValue RHS(LHS.getBitWidth());

642

644 if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;

646

647

648

649 unsigned ThisPrec = PeekPrec;

651

652

653 if (PeekPrec == ~0U) {

655 return true;

656 }

657

658

659

660

661

662

663

664

665

666

667

668 unsigned RHSPrec;

669 if (Operator == tok::question)

670

672 else

673 RHSPrec = ThisPrec+1;

674

675 if (PeekPrec >= RHSPrec) {

677 IncludedUndefinedIds, PP))

678 return true;

680 }

681 assert(PeekPrec <= ThisPrec && "Recursion didn't work!");

682

683

684

685 llvm::APSInt Res(LHS.getBitWidth());

686 switch (Operator) {

687 case tok::question:

688 case tok::lessless:

689 case tok::greatergreater:

690 case tok::comma:

691 case tok::pipepipe:

692 case tok::ampamp:

693 break;

694 default:

695 Res.setIsUnsigned(LHS.isUnsigned() || RHS.isUnsigned());

696

697

698 if (ValueLive && Res.isUnsigned()) {

699 if (!LHS.isUnsigned() && LHS.Val.isNegative())

700 PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 0

701 << toString(LHS.Val, 10, true) + " to " +

703 << LHS.getRange() << RHS.getRange();

704 if (!RHS.isUnsigned() && RHS.Val.isNegative())

705 PP.Diag(OpLoc, diag::warn_pp_convert_to_positive) << 1

706 << toString(RHS.Val, 10, true) + " to " +

708 << LHS.getRange() << RHS.getRange();

709 }

710 LHS.Val.setIsUnsigned(Res.isUnsigned());

711 RHS.Val.setIsUnsigned(Res.isUnsigned());

712 }

713

714 bool Overflow = false;

715 switch (Operator) {

716 default: llvm_unreachable("Unknown operator token!");

717 case tok::percent:

718 if (RHS.Val != 0)

719 Res = LHS.Val % RHS.Val;

720 else if (ValueLive) {

721 PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)

722 << LHS.getRange() << RHS.getRange();

723 return true;

724 }

725 break;

726 case tok::slash:

727 if (RHS.Val != 0) {

728 if (LHS.Val.isSigned())

729 Res = llvm::APSInt(LHS.Val.sdiv_ov(RHS.Val, Overflow), false);

730 else

731 Res = LHS.Val / RHS.Val;

732 } else if (ValueLive) {

733 PP.Diag(OpLoc, diag::err_pp_division_by_zero)

734 << LHS.getRange() << RHS.getRange();

735 return true;

736 }

737 break;

738

739 case tok:⭐

740 if (Res.isSigned())

741 Res = llvm::APSInt(LHS.Val.smul_ov(RHS.Val, Overflow), false);

742 else

743 Res = LHS.Val * RHS.Val;

744 break;

745 case tok::lessless: {

746

747 if (LHS.isUnsigned())

748 Res = LHS.Val.ushl_ov(RHS.Val, Overflow);

749 else

750 Res = llvm::APSInt(LHS.Val.sshl_ov(RHS.Val, Overflow), false);

751 break;

752 }

753 case tok::greatergreater: {

754

755 unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());

756 if (ShAmt >= LHS.getBitWidth()) {

757 Overflow = true;

758 ShAmt = LHS.getBitWidth()-1;

759 }

760 Res = LHS.Val >> ShAmt;

761 break;

762 }

763 case tok:➕

764 if (LHS.isUnsigned())

765 Res = LHS.Val + RHS.Val;

766 else

767 Res = llvm::APSInt(LHS.Val.sadd_ov(RHS.Val, Overflow), false);

768 break;

769 case tok:➖

770 if (LHS.isUnsigned())

771 Res = LHS.Val - RHS.Val;

772 else

773 Res = llvm::APSInt(LHS.Val.ssub_ov(RHS.Val, Overflow), false);

774 break;

775 case tok::lessequal:

776 Res = LHS.Val <= RHS.Val;

777 Res.setIsUnsigned(false);

778 break;

779 case tok::less:

780 Res = LHS.Val < RHS.Val;

781 Res.setIsUnsigned(false);

782 break;

783 case tok::greaterequal:

784 Res = LHS.Val >= RHS.Val;

785 Res.setIsUnsigned(false);

786 break;

787 case tok::greater:

788 Res = LHS.Val > RHS.Val;

789 Res.setIsUnsigned(false);

790 break;

791 case tok::exclaimequal:

792 Res = LHS.Val != RHS.Val;

793 Res.setIsUnsigned(false);

794 break;

795 case tok::equalequal:

796 Res = LHS.Val == RHS.Val;

797 Res.setIsUnsigned(false);

798 break;

799 case tok::amp:

800 Res = LHS.Val & RHS.Val;

801 break;

802 case tok::caret:

803 Res = LHS.Val ^ RHS.Val;

804 break;

805 case tok::pipe:

806 Res = LHS.Val | RHS.Val;

807 break;

808 case tok::ampamp:

809 Res = (LHS.Val != 0 && RHS.Val != 0);

810 Res.setIsUnsigned(false);

811 break;

812 case tok::pipepipe:

813 Res = (LHS.Val != 0 || RHS.Val != 0);

814 Res.setIsUnsigned(false);

815 break;

816 case tok::comma:

817

818

820 PP.Diag(OpLoc, diag::ext_pp_comma_expr)

821 << LHS.getRange() << RHS.getRange();

822 Res = RHS.Val;

823 break;

824 case tok::question: {

825

826 if (PeekTok.isNot(tok::colon)) {

828 << tok::colon << LHS.getRange() << RHS.getRange();

829 PP.Diag(OpLoc, diag::note_matching) << tok::question;

830 return true;

831 }

832

834

835

836 bool AfterColonLive = ValueLive && LHS.Val == 0;

837 PPValue AfterColonVal(LHS.getBitWidth());

839 if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))

840 return true;

841

842

843

845 PeekTok, AfterColonLive,

846 IncludedUndefinedIds, PP))

847 return true;

848

849

850 Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;

851 RHS.setEnd(AfterColonVal.getRange().getEnd());

852

853

854

855 Res.setIsUnsigned(RHS.isUnsigned() || AfterColonVal.isUnsigned());

856

857

859 break;

860 }

861 case tok::colon:

862

863 PP.Diag(OpLoc, diag::err_pp_colon_without_question)

864 << LHS.getRange() << RHS.getRange();

865 return true;

866 }

867

868

869 if (Overflow && ValueLive)

870 PP.Diag(OpLoc, diag::warn_pp_expr_overflow)

871 << LHS.getRange() << RHS.getRange();

872

873

874 LHS.Val = Res;

875 LHS.setEnd(RHS.getRange().getEnd());

876 RHS.setIdentifier(nullptr);

877 }

878}

879

880

881

882

883Preprocessor::DirectiveEvalResult

884Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,

885 Token &Tok, bool &EvaluatedDefined,

886 bool CheckForEoD) {

887 SaveAndRestore PPDir(ParsingIfOrElifDirective, true);

888

889

890

891

892

893

894 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;

895 DisableMacroExpansion = false;

896

897

899

900

902

903 PPValue ResVal(BitWidth);

904 DefinedTracker DT;

905 SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());

907

910

911

912 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

913

914

915

916

917 return {std::nullopt,

918 false,

921 }

922

924

925

926

927

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

929

930

933

934

935 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

936 bool IsNonZero = ResVal.Val != 0;

937 SourceRange ValRange = ResVal.getRange();

939 ValRange};

940 }

941

942

943

946

949

950

951 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

952 return {std::nullopt,

953 false,

956 }

957

958 if (CheckForEoD) {

959

960

962 Diag(Tok, diag::err_pp_expected_eol);

964 }

965 }

966

968

969

970 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

971 bool IsNonZero = ResVal.Val != 0;

972 SourceRange ValRange = ResVal.getRange();

973 return {std::move(ResVal.Val), IsNonZero, DT.IncludedUndefinedIds, ValRange};

974}

975

976Preprocessor::DirectiveEvalResult

977Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,

978 bool CheckForEoD) {

979 Token Tok;

980 bool EvaluatedDefined;

981 return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,

982 CheckForEoD);

983}

984

985static std::optional

989 if (Macro || Macro->getNumTokens() != 1 || Macro->isObjectLike())

990 return std::nullopt;

991

992 const Token &RevisionDateTok = Macro->getReplacementToken(0);

993

996 llvm::StringRef RevisionDate =

999 std::uint64_t Value;

1000

1001 if (!RevisionDate.consumeInteger(10, Value))

1003 }

1005 0};

1006}

1007

1009 if (!CXXStandardLibraryVersion)

1012 if (!CXXStandardLibraryVersion)

1013 return std::nullopt;

1014

1015 if (CXXStandardLibraryVersion->Lib ==

1017 return CXXStandardLibraryVersion->Version;

1018 return std::nullopt;

1019}

1020

1022 assert(FixedVersion >= 2000'00'00 && FixedVersion <= 2100'00'00 &&

1023 "invalid value for __GLIBCXX__");

1025 if (!Ver)

1026 return false;

1027 return *Ver < FixedVersion;

1028}

static bool isUnsigned(SValBuilder &SVB, NonLoc Value)

static uint32_t getBitWidth(const Expr *E)

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

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

Defines the PPCallbacks interface.

static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)

EvaluateValue - Evaluate the token PeekTok (and any others needed) and return the computed value in R...

Definition PPExpressions.cpp:233

static void diagnoseUnexpectedOperator(Preprocessor &PP, PPValue &LHS, Token &Tok)

Definition PPExpressions.cpp:576

static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec, Token &PeekTok, bool ValueLive, bool &IncludedUndefinedIds, Preprocessor &PP)

EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is PeekTok,...

Definition PPExpressions.cpp:592

static std::optional< CXXStandardLibraryVersionInfo > getCXXStandardLibraryVersion(Preprocessor &PP, StringRef MacroName, CXXStandardLibraryVersionInfo::Library Lib)

Definition PPExpressions.cpp:986

static unsigned getPrecedence(tok::TokenKind Kind)

getPrecedence - Return the precedence of the specified binary operator token.

Definition PPExpressions.cpp:547

static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP)

EvaluateDefined - Process a 'defined(sym)' expression.

Definition PPExpressions.cpp:102

static StringRef getIdentifier(const Token &Tok)

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.

static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines the clang::TokenKind enum and support functions.

CharLiteralParser - Perform interpretation and semantic analysis of a character literal.

void setBegin(SourceLocation b)

virtual void CodeCompleteMacroName(bool IsDefinition)

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

virtual void CodeCompletePreprocessorExpression()

Callback invoked when performing code completion in a preprocessor expression, such as the condition ...

std::vector< std::string > UndefPrefixes

The list of prefixes from -Wundef-prefix=... used to generate warnings for undefined macros.

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

DiagnosticOptions & getDiagnosticOptions() const

Retrieve the diagnostic options.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

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

bool isCPlusPlusOperatorKeyword() const

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.

A description of the current definition of a macro.

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

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

This interface provides a way to observe the actions of the preprocessor as it does its thing.

bool SingleFileParseMode

When enabled, preprocessor is in a mode for parsing a single file only.

bool SingleModuleParseMode

When enabled, preprocessor is in a mode for parsing a single module only.

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

PPCallbacks * getPPCallbacks() const

const MacroInfo * getMacroInfo(const IdentifierInfo *II) const

void markMacroAsUsed(MacroInfo *MI)

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

void setCodeCompletionReached()

Note that we hit the code-completion point.

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.

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)

std::optional< std::uint64_t > getStdLibCxxVersion()

Definition PPExpressions.cpp:1008

const TargetInfo & getTargetInfo() const

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

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

bool NeedsStdLibCxxWorkaroundBefore(std::uint64_t FixedVersion)

Definition PPExpressions.cpp:1021

CodeCompletionHandler * getCodeCompletionHandler() const

Retrieve the current code-completion handler.

const PreprocessorOptions & getPreprocessorOpts() const

Retrieve the preprocessor options used to initialize this preprocessor.

const LangOptions & getLangOpts() const

DiagnosticsEngine & getDiagnostics() const

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const

A trivial tuple used to represent a source range.

bool isFunctionMacroExpansion() const

const ExpansionInfo & getExpansion() const

Exposes information about the current target.

unsigned getChar32Width() const

getChar32Width/Align - Return the size of 'char32_t' for this target, in bits.

static bool isTypeSigned(IntType T)

Returns true if the type is signed; false otherwise.

unsigned getChar16Width() const

getChar16Width/Align - Return the size of 'char16_t' for this target, in bits.

unsigned getIntWidth() const

getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...

IntType getWCharType() const

unsigned getWCharWidth() const

getWCharWidth/Align - Return the size of 'wchar_t' for this target, in bits.

unsigned getIntMaxTWidth() const

Return the size of intmax_t and uintmax_t for this target, in bits.

unsigned getCharWidth() const

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

IdentifierInfo * getIdentifierInfo() const

SourceLocation getLocation() const

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

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 isNot(tok::TokenKind K) const

bool hasUDSuffix() const

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

Defines the clang::TargetInfo interface.

TokenKind

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

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

DefinedTracker - This struct is used while parsing expressions to keep track of whether !...

Definition PPExpressions.cpp:87

TrackerState

Each time a Value is evaluated, it returns information about whether the parsed value is of the form ...

Definition PPExpressions.cpp:90

@ Unknown

Definition PPExpressions.cpp:93

@ NotDefinedMacro

Definition PPExpressions.cpp:92

@ DefinedMacro

Definition PPExpressions.cpp:91

bool IncludedUndefinedIds

Definition PPExpressions.cpp:98

IdentifierInfo * TheMacro

TheMacro - When the state is DefinedMacro or NotDefinedMacro, this indicates the macro that was check...

Definition PPExpressions.cpp:97

enum DefinedTracker::TrackerState State