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

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

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

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

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

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

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

36#include

37

38using namespace clang;

39

40namespace {

41

42

43

44class PPValue {

47

48public:

49 llvm::APSInt Val;

50

51

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

53

54

55

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

58

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

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

61

63

67 }

70};

71

72}

73

75 Token &PeekTok, bool ValueLive,

76 bool &IncludedUndefinedIds,

78

79

80

81

82

83

84

85

87

88

92 Unknown

94

95

98};

99

100

104 Result.setBegin(beginLoc);

105

106

108

109

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

112

115 }

116

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

122 }

123

124

126 return true;

127

128

131 Result.Val = !!Macro;

132 Result.Val.setIsUnsigned(false);

134

136 PeekTok,

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

138

139

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

142

143

144 Token macroToken(PeekTok);

145

146

147 if (LParenLoc.isValid()) {

148

151

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

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

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

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

156 return true;

157 }

158

161 } else {

162

165 }

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

186 bool IsFunctionTypeMacro =

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206 if (IsFunctionTypeMacro)

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

208 else

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

210 }

211

212

214 Callbacks->Defined(macroToken, Macro,

216 }

217

218

221 return false;

222}

223

224

225

226

227

228

229

230

231

235

236 Result.setIdentifier(nullptr);

237

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

243 }

244

245 switch (PeekTok.getKind()) {

246 default:

247

248

249

251

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

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

254

256

257

258

259 if (ValueLive) {

260 PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;

261

263

264 if (DiagEngine.isIgnored(diag::warn_pp_undef_identifier,

266 const std::vectorstd::string UndefPrefixes =

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

269 if (llvm::any_of(UndefPrefixes,

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

271 return IdentifierName.starts_with(Prefix);

272 }))

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

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

275 }

276 }

277 Result.Val = 0;

278 Result.Val.setIsUnsigned(false);

279 Result.setIdentifier(II);

283 return false;

284 }

285 }

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

287 return true;

288 case tok::eod:

289 case tok::r_paren:

290

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

292 return true;

293 case tok::numeric_constant: {

295 bool NumberInvalid = false;

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

297 &NumberInvalid);

298 if (NumberInvalid)

299 return true;

300

304 if (Literal.hadError)

305 return true;

306

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

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

309 return true;

310 }

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

312

313

314 if (Literal.hasUDSuffix())

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

316

317

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

320 PP.Diag(PeekTok,

322 diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);

323 else

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

325 }

326

327

328 if (Literal.isSizeT)

331 ? diag::warn_cxx20_compat_size_t_suffix

332 : diag::ext_cxx23_size_t_suffix

333 : diag::err_cxx23_size_t_suffix);

334

335

336

337 if (Literal.isBitInt)

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

340 ? diag::warn_c23_compat_bitint_suffix

341 : diag::ext_c23_bitint_suffix);

342

343

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

345

346 if (ValueLive)

347 PP.Diag(PeekTok, diag::err_integer_literal_too_large)

348 << 1;

349 Result.Val.setIsUnsigned(true);

350 } else {

351

352

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

354

355

356

357

358

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

360

361

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

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

364 Result.Val.setIsUnsigned(true);

365 }

366 }

367

368

371 return false;

372 }

373 case tok::char_constant:

374 case tok::wide_char_constant:

375 case tok::utf8_char_constant:

376 case tok::utf16_char_constant:

377 case tok::utf32_char_constant: {

378

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

381

383 bool CharInvalid = false;

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

385 if (CharInvalid)

386 return true;

387

390 if (Literal.hadError())

391 return true;

392

393

395 unsigned NumBits;

396 if (Literal.isMultiChar())

398 else if (Literal.isWide())

400 else if (Literal.isUTF16())

402 else if (Literal.isUTF32())

404 else

406

407

408 llvm::APSInt Val(NumBits);

409

410 Val = Literal.getValue();

411

412

413 if (Literal.isWide())

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

416 Val.setIsUnsigned(true);

417 else if (Literal.isUTF8()) {

419 Val.setIsUnsigned(

421 else

422 Val.setIsUnsigned(true);

423 } else

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

425

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

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

428 } else {

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

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

431 Result.Val = Val;

432 }

433

434

437 return false;

438 }

439 case tok::l_paren: {

442

443

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

445

446

447

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

449

450 } else {

451

454 return true;

455

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

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

458 << Result.getRange();

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

460 return true;

461 }

463 }

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

465 Result.setIdentifier(nullptr);

467 return false;

468 }

469 case tok:➕ {

471

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

474 Result.setBegin(Start);

475 Result.setIdentifier(nullptr);

476 return false;

477 }

478 case tok:➖ {

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

482 Result.setBegin(Loc);

483 Result.setIdentifier(nullptr);

484

485

486 Result.Val = -Result.Val;

487

488

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

490

491

492 if (Overflow && ValueLive)

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

494

496 return false;

497 }

498

499 case tok::tilde: {

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

503 Result.setBegin(Start);

504 Result.setIdentifier(nullptr);

505

506

507 Result.Val = ~Result.Val;

509 return false;

510 }

511

512 case tok::exclaim: {

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

516 Result.setBegin(Start);

517 Result.Val = !Result.Val;

518

519 Result.Val.setIsUnsigned(false);

520 Result.setIdentifier(nullptr);

521

526 return false;

527 }

528 case tok::kw_true:

529 case tok::kw_false:

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

531 Result.Val.setIsUnsigned(false);

535 return false;

536

537

538 }

539}

540

541

542

543

544

545

547 switch (Kind) {

548 default: return ~0U;

549 case tok::percent:

550 case tok::slash:

551 case tok:⭐ return 14;

552 case tok:➕

553 case tok:➖ return 13;

554 case tok::lessless:

555 case tok::greatergreater: return 12;

556 case tok::lessequal:

557 case tok::less:

558 case tok::greaterequal:

559 case tok::greater: return 11;

560 case tok::exclaimequal:

561 case tok::equalequal: return 10;

562 case tok::amp: return 9;

563 case tok::caret: return 8;

564 case tok::pipe: return 7;

565 case tok::ampamp: return 6;

566 case tok::pipepipe: return 5;

567 case tok::question: return 4;

568 case tok::comma: return 3;

569 case tok::colon: return 2;

570 case tok::r_paren: return 0;

571 case tok::eod: return 0;

572 }

573}

574

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

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

579 << LHS.getIdentifier();

580 else

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

582 << LHS.getRange();

583}

584

585

586

587

588

589

590

592 Token &PeekTok, bool ValueLive,

593 bool &IncludedUndefinedIds,

596

597 if (PeekPrec == ~0U) {

599 return true;

600 }

601

602 while (true) {

603

604

605 if (PeekPrec < MinPrec)

606 return false;

607

609

610

611

612

613

614

615 bool RHSIsLive;

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

617 RHSIsLive = false;

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

619 RHSIsLive = false;

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

621 RHSIsLive = false;

622 else

623 RHSIsLive = ValueLive;

624

625

628

629 PPValue RHS(LHS.getBitWidth());

630

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

634

635

636

637 unsigned ThisPrec = PeekPrec;

639

640

641 if (PeekPrec == ~0U) {

643 return true;

644 }

645

646

647

648

649

650

651

652

653

654

655

656 unsigned RHSPrec;

657 if (Operator == tok::question)

658

660 else

661 RHSPrec = ThisPrec+1;

662

663 if (PeekPrec >= RHSPrec) {

665 IncludedUndefinedIds, PP))

666 return true;

668 }

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

670

671

672

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

674 switch (Operator) {

675 case tok::question:

676 case tok::lessless:

677 case tok::greatergreater:

678 case tok::comma:

679 case tok::pipepipe:

680 case tok::ampamp:

681 break;

682 default:

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

684

685

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

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

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

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

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

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

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

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

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

697 }

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

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

700 }

701

702 bool Overflow = false;

703 switch (Operator) {

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

705 case tok::percent:

706 if (RHS.Val != 0)

707 Res = LHS.Val % RHS.Val;

708 else if (ValueLive) {

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

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

711 return true;

712 }

713 break;

714 case tok::slash:

715 if (RHS.Val != 0) {

716 if (LHS.Val.isSigned())

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

718 else

719 Res = LHS.Val / RHS.Val;

720 } else if (ValueLive) {

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

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

723 return true;

724 }

725 break;

726

727 case tok:⭐

728 if (Res.isSigned())

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

730 else

731 Res = LHS.Val * RHS.Val;

732 break;

733 case tok::lessless: {

734

735 if (LHS.isUnsigned())

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

737 else

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

739 break;

740 }

741 case tok::greatergreater: {

742

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

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

745 Overflow = true;

746 ShAmt = LHS.getBitWidth()-1;

747 }

748 Res = LHS.Val >> ShAmt;

749 break;

750 }

751 case tok:➕

752 if (LHS.isUnsigned())

753 Res = LHS.Val + RHS.Val;

754 else

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

756 break;

757 case tok:➖

758 if (LHS.isUnsigned())

759 Res = LHS.Val - RHS.Val;

760 else

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

762 break;

763 case tok::lessequal:

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

765 Res.setIsUnsigned(false);

766 break;

767 case tok::less:

768 Res = LHS.Val < RHS.Val;

769 Res.setIsUnsigned(false);

770 break;

771 case tok::greaterequal:

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

773 Res.setIsUnsigned(false);

774 break;

775 case tok::greater:

776 Res = LHS.Val > RHS.Val;

777 Res.setIsUnsigned(false);

778 break;

779 case tok::exclaimequal:

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

781 Res.setIsUnsigned(false);

782 break;

783 case tok::equalequal:

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

785 Res.setIsUnsigned(false);

786 break;

787 case tok::amp:

788 Res = LHS.Val & RHS.Val;

789 break;

790 case tok::caret:

791 Res = LHS.Val ^ RHS.Val;

792 break;

793 case tok::pipe:

794 Res = LHS.Val | RHS.Val;

795 break;

796 case tok::ampamp:

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

798 Res.setIsUnsigned(false);

799 break;

800 case tok::pipepipe:

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

802 Res.setIsUnsigned(false);

803 break;

804 case tok::comma:

805

806

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

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

810 Res = RHS.Val;

811 break;

812 case tok::question: {

813

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

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

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

818 return true;

819 }

820

822

823

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

825 PPValue AfterColonVal(LHS.getBitWidth());

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

828 return true;

829

830

831

833 PeekTok, AfterColonLive,

834 IncludedUndefinedIds, PP))

835 return true;

836

837

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

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

840

841

842

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

844

845

847 break;

848 }

849 case tok::colon:

850

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

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

853 return true;

854 }

855

856

857 if (Overflow && ValueLive)

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

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

860

861

862 LHS.Val = Res;

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

864 RHS.setIdentifier(nullptr);

865 }

866}

867

868

869

870

871Preprocessor::DirectiveEvalResult

872Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,

873 Token &Tok, bool &EvaluatedDefined,

874 bool CheckForEoD) {

875 SaveAndRestore PPDir(ParsingIfOrElifDirective, true);

876

877

878

879

880

881

882 bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;

883 DisableMacroExpansion = false;

884

885

887

888

890

891 PPValue ResVal(BitWidth);

894 if (EvaluateValue(ResVal, Tok, DT, true, *this)) {

895

896 SourceRange ConditionRange = ExprStartLoc;

897 if (Tok.isNot(tok::eod))

899

900

901 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

902

903

904

905

906 return {std::nullopt,

907 false,

909 {ExprStartLoc, ConditionRange.getEnd()}};

910 }

911

913

914

915

916

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

918

919

922

923

924 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

925 bool IsNonZero = ResVal.Val != 0;

926 SourceRange ValRange = ResVal.getRange();

928 ValRange};

929 }

930

931

932

935

936 if (Tok.isNot(tok::eod))

938

939

940 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

941 SourceRange ValRange = ResVal.getRange();

943 }

944

945 if (CheckForEoD) {

946

947

948 if (Tok.isNot(tok::eod)) {

949 Diag(Tok, diag::err_pp_expected_eol);

951 }

952 }

953

955

956

957 DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;

958 bool IsNonZero = ResVal.Val != 0;

959 SourceRange ValRange = ResVal.getRange();

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

961}

962

963Preprocessor::DirectiveEvalResult

964Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,

965 bool CheckForEoD) {

967 bool EvaluatedDefined;

968 return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined,

969 CheckForEoD);

970}

static bool isUnsigned(SValBuilder &SVB, NonLoc Value)

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

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

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

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

static unsigned getPrecedence(tok::TokenKind Kind)

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

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

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

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.

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.

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.

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

PPCallbacks * getPPCallbacks() 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.

SourceManager & getSourceManager() const

MacroDefinition getMacroDefinition(const IdentifierInfo *II)

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

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

CodeCompletionHandler * getCodeCompletionHandler() const

Retrieve the current code-completion handler.

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.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

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

A trivial tuple used to represent a source range.

void setBegin(SourceLocation b)

SourceLocation getEnd() const

void setEnd(SourceLocation e)

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

TrackerState

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

bool IncludedUndefinedIds

IdentifierInfo * TheMacro

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

enum DefinedTracker::TrackerState State