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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

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

36#include "llvm/ADT/DenseSet.h"

37#include "llvm/ADT/FoldingSet.h"

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

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

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

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

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

43#include "llvm/Support/Format.h"

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

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

46#include

47#include

48#include

49#include

50#include

51#include

52#include

53#include

54#include

55#include

56#include

57

58using namespace clang;

59

63 return nullptr;

64 auto Pos = CurSubmoduleState->Macros.find(II);

65 return Pos == CurSubmoduleState->Macros.end() ? nullptr

66 : Pos->second.getLatest();

67}

68

70 assert(MD && "MacroDirective should be non-zero!");

71 assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");

72

73 MacroState &StoredMD = CurSubmoduleState->Macros[II];

74 auto *OldMD = StoredMD.getLatest();

76 StoredMD.setLatest(MD);

77 StoredMD.overrideActiveModuleMacros(*this, II);

78

79 if (needModuleMacros()) {

80

81

82

83 PendingModuleMacroNames.push_back(II);

84 }

85

86

88 if (!MD->isDefined() && !LeafModuleMacros.contains(II))

92}

93

97

98

99

100

101

102

103

104

105

106 assert(II && MD);

107 MacroState &StoredMD = CurSubmoduleState->Macros[II];

108

109 if (auto *OldMD = StoredMD.getLatest()) {

110

111

112

113

114

115 assert(OldMD->getMacroInfo()->isBuiltinMacro() &&

116 "only built-ins should have an entry here");

117 assert(!OldMD->getPrevious() && "builtin should only have a single entry");

119 StoredMD.setLatest(MD);

120 } else {

121 StoredMD = MD;

122 }

123

124

126 if (!MD->isDefined() && !LeafModuleMacros.contains(II))

128}

129

133 bool &New) {

134 llvm::FoldingSetNodeID ID;

136

137 void *InsertPos;

138 if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {

139 New = false;

140 return MM;

141 }

142

144 ModuleMacros.InsertNode(MM, InsertPos);

145

146

147 bool HidAny = false;

148 for (auto *O : Overrides) {

149 HidAny |= (O->NumOverriddenBy == 0);

150 ++O->NumOverriddenBy;

151 }

152

153

154 auto &LeafMacros = LeafModuleMacros[II];

155 if (HidAny) {

156 llvm::erase_if(LeafMacros,

157 [](ModuleMacro *MM) { return MM->NumOverriddenBy != 0; });

158 }

159

160

161 LeafMacros.push_back(MM);

162

164

165 New = true;

166 return MM;

167}

168

171 llvm::FoldingSetNodeID ID;

173

174 void *InsertPos;

175 return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);

176}

177

178void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II,

179 ModuleMacroInfo &Info) {

180 assert(Info.ActiveModuleMacrosGeneration !=

181 CurSubmoduleState->VisibleModules.getGeneration() &&

182 "don't need to update this macro name info");

183 Info.ActiveModuleMacrosGeneration =

184 CurSubmoduleState->VisibleModules.getGeneration();

185

186 auto Leaf = LeafModuleMacros.find(II);

187 if (Leaf == LeafModuleMacros.end()) {

188

189 return;

190 }

191

192 Info.ActiveModuleMacros.clear();

193

194

195 llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;

196 for (auto *O : Info.OverriddenMacros)

197 NumHiddenOverrides[O] = -1;

198

199

201 for (auto *LeafMM : Leaf->second) {

202 assert(LeafMM->getNumOverridingMacros() == 0 && "leaf macro overridden");

203 if (NumHiddenOverrides.lookup(LeafMM) == 0)

204 Worklist.push_back(LeafMM);

205 }

206 while (!Worklist.empty()) {

207 auto *MM = Worklist.pop_back_val();

208 if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {

209

210

211 if (MM->getMacroInfo())

212 Info.ActiveModuleMacros.push_back(MM);

213 } else {

214 for (auto *O : MM->overrides())

215 if ((unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())

216 Worklist.push_back(O);

217 }

218 }

219

220 std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());

221

222

223 MacroInfo *MI = nullptr;

224 bool IsSystemMacro = true;

225 bool IsAmbiguous = false;

226 if (auto *MD = Info.MD) {

227 while (isa_and_nonnull(MD))

228 MD = MD->getPrevious();

229 if (auto *DMD = dyn_cast_or_null(MD)) {

230 MI = DMD->getInfo();

231 IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation());

232 }

233 }

234 for (auto *Active : Info.ActiveModuleMacros) {

235 auto *NewMI = Active->getMacroInfo();

236

237

238

239

240

241

242

243

244

245

246 if (MI && NewMI != MI &&

247 !MI->isIdenticalTo(*NewMI, *this, true))

248 IsAmbiguous = true;

249 IsSystemMacro &= Active->getOwningModule()->IsSystem ||

250 SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());

251 MI = NewMI;

252 }

253 Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;

254}

255

258 auto LeafIt = LeafModuleMacros.find(II);

259 if (LeafIt != LeafModuleMacros.end())

260 Leaf = LeafIt->second;

261 const MacroState *State = nullptr;

262 auto Pos = CurSubmoduleState->Macros.find(II);

263 if (Pos != CurSubmoduleState->Macros.end())

264 State = &Pos->second;

265

266 llvm::errs() << "MacroState " << State << " " << II->getNameStart();

267 if (State && State->isAmbiguous(*this, II))

268 llvm::errs() << " ambiguous";

269 if (State && !State->getOverriddenMacros().empty()) {

270 llvm::errs() << " overrides";

271 for (auto *O : State->getOverriddenMacros())

272 llvm::errs() << " " << O->getOwningModule()->getFullModuleName();

273 }

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

275

276

277 for (auto *MD = State ? State->getLatest() : nullptr; MD;

278 MD = MD->getPrevious()) {

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

280 MD->dump();

281 }

282

283

284 llvm::DenseSet<ModuleMacro*> Active;

285 for (auto *MM : State ? State->getActiveModuleMacros(*this, II)

287 Active.insert(MM);

288 llvm::DenseSet<ModuleMacro*> Visited;

290 while (!Worklist.empty()) {

291 auto *MM = Worklist.pop_back_val();

292 llvm::errs() << " ModuleMacro " << MM << " "

293 << MM->getOwningModule()->getFullModuleName();

294 if (!MM->getMacroInfo())

295 llvm::errs() << " undef";

296

297 if (Active.count(MM))

298 llvm::errs() << " active";

299 else if (!CurSubmoduleState->VisibleModules.isVisible(

300 MM->getOwningModule()))

301 llvm::errs() << " hidden";

302 else if (MM->getMacroInfo())

303 llvm::errs() << " overridden";

304

305 if (!MM->overrides().empty()) {

306 llvm::errs() << " overrides";

307 for (auto *O : MM->overrides()) {

308 llvm::errs() << " " << O->getOwningModule()->getFullModuleName();

309 if (Visited.insert(O).second)

310 Worklist.push_back(O);

311 }

312 }

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

314 if (auto *MI = MM->getMacroInfo()) {

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

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

318 }

319 }

320}

321

322

323

324void Preprocessor::RegisterBuiltinMacros() {

325 Ident__LINE__ = RegisterBuiltinMacro("__LINE__");

326 Ident__FILE__ = RegisterBuiltinMacro("__FILE__");

327 Ident__DATE__ = RegisterBuiltinMacro("__DATE__");

328 Ident__TIME__ = RegisterBuiltinMacro("__TIME__");

329 Ident__COUNTER__ = RegisterBuiltinMacro("__COUNTER__");

330 Ident_Pragma = RegisterBuiltinMacro("_Pragma");

331 Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro("__FLT_EVAL_METHOD__");

332

333

335 Ident__has_cpp_attribute = RegisterBuiltinMacro("__has_cpp_attribute");

336 else

337 Ident__has_cpp_attribute = nullptr;

338

339

340 Ident__BASE_FILE__ = RegisterBuiltinMacro("__BASE_FILE__");

341 Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro("__INCLUDE_LEVEL__");

342 Ident__TIMESTAMP__ = RegisterBuiltinMacro("__TIMESTAMP__");

343

344

346 Ident__identifier = RegisterBuiltinMacro("__identifier");

347 Ident__pragma = RegisterBuiltinMacro("__pragma");

348 } else {

349 Ident__identifier = nullptr;

350 Ident__pragma = nullptr;

351 }

352

353

354 Ident__FILE_NAME__ = RegisterBuiltinMacro("__FILE_NAME__");

355 Ident__has_feature = RegisterBuiltinMacro("__has_feature");

356 Ident__has_extension = RegisterBuiltinMacro("__has_extension");

357 Ident__has_builtin = RegisterBuiltinMacro("__has_builtin");

358 Ident__has_constexpr_builtin =

359 RegisterBuiltinMacro("__has_constexpr_builtin");

360 Ident__has_attribute = RegisterBuiltinMacro("__has_attribute");

362 Ident__has_c_attribute = RegisterBuiltinMacro("__has_c_attribute");

363 else

364 Ident__has_c_attribute = nullptr;

365

366 Ident__has_declspec = RegisterBuiltinMacro("__has_declspec_attribute");

367 Ident__has_embed = RegisterBuiltinMacro("__has_embed");

368 Ident__has_include = RegisterBuiltinMacro("__has_include");

369 Ident__has_include_next = RegisterBuiltinMacro("__has_include_next");

370 Ident__has_warning = RegisterBuiltinMacro("__has_warning");

371 Ident__is_identifier = RegisterBuiltinMacro("__is_identifier");

372 Ident__is_target_arch = RegisterBuiltinMacro("__is_target_arch");

373 Ident__is_target_vendor = RegisterBuiltinMacro("__is_target_vendor");

374 Ident__is_target_os = RegisterBuiltinMacro("__is_target_os");

375 Ident__is_target_environment =

376 RegisterBuiltinMacro("__is_target_environment");

377 Ident__is_target_variant_os = RegisterBuiltinMacro("__is_target_variant_os");

378 Ident__is_target_variant_environment =

379 RegisterBuiltinMacro("__is_target_variant_environment");

380

381

382 Ident__building_module = RegisterBuiltinMacro("__building_module");

383 if (getLangOpts().CurrentModule.empty())

384 Ident__MODULE__ = RegisterBuiltinMacro("__MODULE__");

385 else

386 Ident__MODULE__ = nullptr;

387}

388

389

390

395

396

397 if (!II) return true;

398

399

400

403

404

405

407 if (ExpansionMI->isEnabled() &&

408

409 II != MacroIdent)

410 return false;

411

412

413

415

416

417

418 return !llvm::is_contained(MI->params(), II);

419}

420

421

422

423bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,

426

428

429

430

431

432 if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();

433

434

436 if (Callbacks)

437 Callbacks->MacroExpands(Identifier, M, Identifier.getLocation(),

438 nullptr);

439 ExpandBuiltinMacro(Identifier);

440 return true;

441 }

442

443

444

445

447

448

449

450 SourceLocation ExpansionEnd = Identifier.getLocation();

451

452

454

455

456

457 InMacroArgs = true;

458 ArgMacro = &Identifier;

459

460 Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);

461

462

463 InMacroArgs = false;

464 ArgMacro = nullptr;

465

466

467 if (!Args) return true;

468

469 ++NumFnMacroExpanded;

470 } else {

471 ++NumMacroExpanded;

472 }

473

474

476

477

478 SourceLocation ExpandLoc = Identifier.getLocation();

479 SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);

480

481 if (Callbacks) {

482 if (InMacroArgs) {

483

484

485

486

487 DelayedMacroExpandsCallbacks.push_back(

488 MacroExpandsInfo(Identifier, M, ExpansionRange));

489 } else {

490 Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);

491 if (!DelayedMacroExpandsCallbacks.empty()) {

492 for (const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {

493

494 Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,

495 nullptr);

496 }

497 DelayedMacroExpandsCallbacks.clear();

498 }

499 }

500 }

501

502

504 Diag(Identifier, diag::warn_pp_ambiguous_macro)

509 if (OtherMI != MI)

512 });

513 }

514

515

516

517

518

520

521 if (Args) Args->destroy(*this);

522

523

524

526 PropagateLineStartLeadingSpaceInfo(Identifier);

527 ++NumFastMacroExpanded;

528 return false;

531 *this)) {

532

533

534

535

536

537 if (Args) Args->destroy(*this);

538

539

540

543

544

546

547

550

551

552

553 SourceLocation Loc =

554 SourceMgr.createExpansionLoc(Identifier.getLocation(), ExpandLoc,

555 ExpansionEnd,Identifier.getLength());

557

558

559

562 if (!NewMI->isEnabled() || NewMI == MI) {

564

565

567 Diag(Identifier, diag::pp_disabled_macro_expansion);

568 }

569 }

570

571

572

573 ++NumFastMacroExpanded;

574 return true;

575 }

576

577

578 EnterMacro(Identifier, ExpansionEnd, MI, Args);

579 return false;

580}

581

586

587

588

592 E = Tokens.end();

593 I != E; ++I) {

594 if (I->is(tok::l_paren)) {

595 Brackets.push_back(Paren);

596 } else if (I->is(tok::r_paren)) {

597 if (Brackets.empty() || Brackets.back() == Brace)

598 return false;

599 Brackets.pop_back();

600 } else if (I->is(tok::l_brace)) {

601 Brackets.push_back(Brace);

602 } else if (I->is(tok::r_brace)) {

603 if (Brackets.empty() || Brackets.back() == Paren)

604 return false;

605 Brackets.pop_back();

606 }

607 }

608 return Brackets.empty();

609}

610

611

612

613

614

615

616

617

621 unsigned &NumArgs,

625 return false;

626

627

628

630

631

633

634

635

637 NumArgs = 0;

639

640

641

642 bool FoundSeparatorToken = false;

644 E = OldTokens.end();

645 I != E; ++I) {

646 if (I->is(tok::l_brace)) {

648 } else if (I->is(tok::r_brace)) {

650 if (Braces == 0 && ClosingBrace == E && FoundSeparatorToken)

651 ClosingBrace = I;

652 } else if (I->is(tok::eof)) {

653

655

656

657 FoundSeparatorToken = true;

658 I->setKind(tok::comma);

659 I->setLength(1);

660 } else {

661

662 ++NumArgs;

663

664

665

666 if (FoundSeparatorToken && ArgStartIterator->is(tok::l_brace)) {

667 InitLists.push_back(

668 SourceRange(ArgStartIterator->getLocation(),

670 ClosingBrace = E;

671 }

672

673

674 if (FoundSeparatorToken) {

676 TempToken.setKind(tok::l_paren);

677 TempToken.setLocation(ArgStartIterator->getLocation());

679 NewTokens.push_back(TempToken);

680 }

681

682

683 NewTokens.insert(NewTokens.end(), ArgStartIterator, I);

684

685

686 if (FoundSeparatorToken) {

689 TempToken.setKind(tok::r_paren);

692 NewTokens.push_back(TempToken);

693 ParenHints.push_back(SourceRange(ArgStartIterator->getLocation(),

694 Loc));

695 }

696

697

698 NewTokens.push_back(*I);

699

700

701 ArgStartIterator = I + 1;

702 FoundSeparatorToken = false;

703 }

704 }

705 }

706

707 return !ParenHints.empty() && InitLists.empty();

708}

709

710

711

712

713

714MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,

717

718 unsigned NumFixedArgsLeft = MI->getNumParams();

720

721

722 Token Tok;

723

724

725

727 assert(Tok.is(tok::l_paren) && "Error computing l-paren-ness?");

728

729

730

731

732 SmallVector<Token, 64> ArgTokens;

733 bool ContainsCodeCompletionTok = false;

734 bool FoundElidedComma = false;

735

736 SourceLocation TooManyArgsLoc;

737

738 unsigned NumActuals = 0;

739 while (Tok.isNot(tok::r_paren)) {

740 if (ContainsCodeCompletionTok && Tok.isOneOf(tok::eof, tok::eod))

741 break;

742

743 assert(Tok.isOneOf(tok::l_paren, tok::comma) &&

744 "only expect argument separators here");

745

746 size_t ArgTokenStart = ArgTokens.size();

748

749

750

751 unsigned NumParens = 0;

752

753 while (true) {

754

755

757

758 if (Tok.isOneOf(tok::eof, tok::eod)) {

759 if (!ContainsCodeCompletionTok) {

760 Diag(MacroName, diag::err_unterm_macro_invoc);

763

764 MacroName = Tok;

765 return nullptr;

766 }

767

768 auto Toks = std::make_unique<Token[]>(1);

769 Toks[0] = Tok;

770 EnterTokenStream(std::move(Toks), 1, true, false);

771 break;

772 } else if (Tok.is(tok::r_paren)) {

773

774 if (NumParens-- == 0) {

776 if (!ArgTokens.empty() &&

777 ArgTokens.back().commaAfterElided()) {

778 FoundElidedComma = true;

779 }

780 break;

781 }

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

783 ++NumParens;

784 } else if (Tok.is(tok::comma)) {

785

786

787

789

790

791

792

793

795 } else if (NumParens == 0) {

796

797

798

799 if (!isVariadic)

800 break;

801 if (NumFixedArgsLeft > 1)

802 break;

803 }

804 } else if (Tok.is(tok::comment) && !KeepMacroComments) {

805

806

807 continue;

809

810

811

812

813

814

818 } else if (Tok.is(tok::code_completion)) {

819 ContainsCodeCompletionTok = true;

820 if (CodeComplete)

821 CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),

822 MI, NumActuals);

823

824

825

826 }

827

828 ArgTokens.push_back(Tok);

829 }

830

831

832

833 if (ArgTokens.empty() && Tok.getKind() == tok::r_paren)

834 break;

835

836

837

838 if (!isVariadic && NumFixedArgsLeft == 0 && TooManyArgsLoc.isInvalid()) {

839 if (ArgTokens.size() != ArgTokenStart)

840 TooManyArgsLoc = ArgTokens[ArgTokenStart].getLocation();

841 else

842 TooManyArgsLoc = ArgStartLoc;

843 }

844

845

846

847 if (ArgTokens.size() == ArgTokenStart && getLangOpts().C99)

849 ? diag::warn_cxx98_compat_empty_fnmacro_arg

850 : diag::ext_empty_fnmacro_arg);

851

852

853 Token EOFTok;

855 EOFTok.setKind(tok::eof);

858 ArgTokens.push_back(EOFTok);

859 ++NumActuals;

860 if (!ContainsCodeCompletionTok && NumFixedArgsLeft != 0)

861 --NumFixedArgsLeft;

862 }

863

864

865

866 unsigned MinArgsExpected = MI->getNumParams();

867

868

869

870 if (!isVariadic && NumActuals > MinArgsExpected &&

871 !ContainsCodeCompletionTok) {

872

873

874 Diag(TooManyArgsLoc, diag::err_too_many_args_in_macro_invoc);

877

878

879

880

881

882

883 SmallVector<Token, 4> FixedArgTokens;

884 unsigned FixedNumArgs = 0;

885 SmallVector<SourceRange, 4> ParenHints, InitLists;

887 ParenHints, InitLists)) {

888 if (!InitLists.empty()) {

889 DiagnosticBuilder DB =

890 Diag(MacroName,

891 diag::note_init_list_at_beginning_of_macro_argument);

892 for (SourceRange Range : InitLists)

894 }

895 return nullptr;

896 }

897 if (FixedNumArgs != MinArgsExpected)

898 return nullptr;

899

900 DiagnosticBuilder DB = Diag(MacroName, diag::note_suggest_parens_for_macro);

901 for (SourceRange ParenLocation : ParenHints) {

904 }

905 ArgTokens.swap(FixedArgTokens);

906 NumActuals = FixedNumArgs;

907 }

908

909

910 bool isVarargsElided = false;

911

912 if (ContainsCodeCompletionTok) {

913

914 Token EOFTok;

916 EOFTok.setKind(tok::eof);

919 for (; NumActuals < MinArgsExpected; ++NumActuals)

920 ArgTokens.push_back(EOFTok);

921 }

922

923 if (NumActuals < MinArgsExpected) {

924

925 if (NumActuals == 0 && MinArgsExpected == 1) {

926

927

928

929

930

932 } else if ((FoundElidedComma || MI->isVariadic()) &&

933 (NumActuals+1 == MinArgsExpected ||

934 (NumActuals == 0 && MinArgsExpected == 2))) {

935

936

937

938

939

940

942

943

944

945

946 unsigned ID;

948 ID = diag::warn_cxx17_compat_missing_varargs_arg;

950 ID = diag::ext_cxx_missing_varargs_arg;

952 ID = diag::warn_c17_compat_missing_varargs_arg;

953 else

954 ID = diag::ext_c_missing_varargs_arg;

958 }

959

960

961

962

963

964

965

966 isVarargsElided = true;

967 } else if (!ContainsCodeCompletionTok) {

968

969 Diag(Tok, diag::err_too_few_args_in_macro_invoc);

972 return nullptr;

973 }

974

975

981 ArgTokens.push_back(Tok);

982

983

984 if (NumActuals == 0 && MinArgsExpected == 2)

985 ArgTokens.push_back(Tok);

986

987 } else if (NumActuals > MinArgsExpected && !MI->isVariadic() &&

988 !ContainsCodeCompletionTok) {

989

990

991 Diag(MacroName, diag::err_too_many_args_in_macro_invoc);

994 return nullptr;

995 }

996

998}

999

1000

1001

1002

1003

1004

1005Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,

1007 assert(tokLexer);

1008 if (tokens.empty())

1009 return nullptr;

1010

1011 size_t newIndex = MacroExpandedTokens.size();

1012 bool cacheNeedsToGrow = tokens.size() >

1013 MacroExpandedTokens.capacity()-MacroExpandedTokens.size();

1014 MacroExpandedTokens.append(tokens.begin(), tokens.end());

1015

1016 if (cacheNeedsToGrow) {

1017

1018

1019 for (const auto &Lexer : MacroExpandingLexersStack) {

1020 TokenLexer *prevLexer;

1021 size_t tokIndex;

1022 std::tie(prevLexer, tokIndex) = Lexer;

1023 prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;

1024 }

1025 }

1026

1027 MacroExpandingLexersStack.push_back(std::make_pair(tokLexer, newIndex));

1028 return MacroExpandedTokens.data() + newIndex;

1029}

1030

1031void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() {

1032 assert(!MacroExpandingLexersStack.empty());

1033 size_t tokIndex = MacroExpandingLexersStack.back().second;

1034 assert(tokIndex < MacroExpandedTokens.size());

1035

1036 MacroExpandedTokens.resize(tokIndex);

1037 MacroExpandingLexersStack.pop_back();

1038}

1039

1040

1041

1042

1045 time_t TT;

1046 std::tm *TM;

1049 TM = std::gmtime(&TT);

1050 } else {

1051 TT = std::time(nullptr);

1052 TM = std::localtime(&TT);

1053 }

1054

1055 static const char * const Months[] = {

1056 "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"

1057 };

1058

1059 {

1061 llvm::raw_svector_ostream TmpStream(TmpBuffer);

1062 if (TM)

1063 TmpStream << llvm::format("\"%s %2d %4d\"", Months[TM->tm_mon],

1064 TM->tm_mday, TM->tm_year + 1900);

1065 else

1066 TmpStream << "??? ?? ????";

1071 }

1072

1073 {

1075 llvm::raw_svector_ostream TmpStream(TmpBuffer);

1076 if (TM)

1077 TmpStream << llvm::format("\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min,

1078 TM->tm_sec);

1079 else

1080 TmpStream << "??:??:??";

1085 }

1086}

1087

1088

1089

1092

1093

1094 if (Feature.starts_with("__") && Feature.ends_with("__") &&

1097

1098#define FEATURE(Name, Predicate) .Case(#Name, Predicate)

1099 return llvm::StringSwitch(Feature)

1100#include "clang/Basic/Features.def"

1101 .Default(false);

1102#undef FEATURE

1103}

1104

1105

1106

1107

1110 return true;

1111

1112

1113

1116 return false;

1117

1119

1120

1121 if (Extension.starts_with("__") && Extension.ends_with("__") &&

1122 Extension.size() >= 4)

1123 Extension = Extension.substr(2, Extension.size() - 4);

1124

1125

1126

1127#define EXTENSION(Name, Predicate) .Case(#Name, Predicate)

1128 return llvm::StringSwitch(Extension)

1129#include "clang/Basic/Features.def"

1130 .Default(false);

1131#undef EXTENSION

1132}

1133

1134

1135

1136

1140 const FileEntry *LookupFromFile) {

1141

1142

1144

1145

1147 PP.Diag(LParenLoc, diag::err_pp_directive_required) << II;

1148

1149 assert(Tok.is(tok::identifier));

1150 Tok.setIdentifierInfo(II);

1151 return false;

1152 }

1153

1154

1155 do {

1157 return false;

1158 } while (Tok.getKind() == tok::comment);

1159

1160

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

1162

1164 PP.Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;

1165

1166

1167 if (Tok.isNot(tok::header_name))

1168 return false;

1169 } else {

1170

1171 LParenLoc = Tok.getLocation();

1173 return false;

1174 }

1175

1176 if (Tok.isNot(tok::header_name)) {

1177 PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);

1178 return false;

1179 }

1180

1181

1186 return false;

1187

1189

1190

1192

1193

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

1196 << II << tok::r_paren;

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

1198 return false;

1199 }

1200

1202

1203

1204 if (Filename.empty())

1205 return false;

1206

1207

1208

1209

1211

1212

1214 PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,

1215 nullptr, nullptr, nullptr, &KH, nullptr, nullptr);

1216

1221 Callbacks->HasInclude(FilenameLoc, Filename, isAngled, File, FileType);

1222 }

1223

1224

1225 return File.has_value();

1226}

1227

1228

1229

1231

1233 Diag(Tok, diag::err_pp_directive_required) << II;

1234

1235 assert(Tok.is(tok::identifier));

1238 }

1239

1240

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

1243 Diag(Tok, diag::err_pp_expected_after) << II << tok::l_paren;

1244

1245

1247 }

1248

1249

1250

1254

1255 if (Tok.isNot(tok::header_name)) {

1258 }

1259

1261 Token FilenameTok = Tok;

1262

1263 std::optional Params =

1265

1266 if (!Params)

1268

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

1271 << II << tok::r_paren;

1272 Diag(LParenLoc, diag::note_matching) << tok::l_paren;

1276 }

1277

1278 if (Params->UnrecognizedParams > 0)

1280

1281 SmallString<128> FilenameBuffer;

1282 StringRef Filename = this->getSpelling(FilenameTok, FilenameBuffer);

1283 if (Filename.empty())

1285

1286 bool isAngled =

1288

1289

1290 const FileEntry *LookupFromFile =

1292 : static_cast<FileEntry *>(nullptr);

1294 this->LookupEmbedFile(Filename, isAngled, false, LookupFromFile);

1295 if (Callbacks) {

1296 Callbacks->HasEmbed(LParenLoc, Filename, isAngled, MaybeFileEntry);

1297 }

1298 if (!MaybeFileEntry)

1300

1301 size_t FileSize = MaybeFileEntry->getSize();

1302

1303

1304 if (Params->MaybeOffsetParam) {

1305 if (Params->MaybeOffsetParam->Offset > FileSize)

1306 FileSize = 0;

1307 else

1308 FileSize -= Params->MaybeOffsetParam->Offset;

1309 }

1310

1311

1312

1313 if (Params->MaybeLimitParam) {

1314 if (Params->MaybeLimitParam->Limit > FileSize)

1315 FileSize = 0;

1316 else

1317 FileSize = Params->MaybeLimitParam->Limit;

1318 }

1319

1320

1321

1322 if (FileSize == 0)

1325}

1326

1329}

1330

1333 const FileEntry *LookupFromFile;

1334 std::tie(Lookup, LookupFromFile) = getIncludeNextStart(Tok);

1335

1337}

1338

1339

1340

1344 llvm::function_ref<

1346 bool &HasLexedNextTok)> Op) {

1347

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

1350 PP.Diag(Tok.getLocation(), diag::err_pp_expected_after) << II

1351 << tok::l_paren;

1352

1353

1354 if (Tok.isOneOf(tok::eof, tok::eod)) {

1355 OS << 0;

1356 Tok.setKind(tok::numeric_constant);

1357 }

1358 return;

1359 }

1360

1361 unsigned ParenDepth = 1;

1363 std::optional Result;

1364

1365 Token ResultTok;

1366 bool SuppressDiagnostic = false;

1367 while (true) {

1368

1369 if (ExpandArgs)

1371 else

1373

1374already_lexed:

1375 switch (Tok.getKind()) {

1376 case tok::eof:

1377 case tok::eod:

1378

1379

1380 PP.Diag(Tok.getLocation(), diag::err_unterm_macro_invoc);

1381 return;

1382

1383 case tok::comma:

1384 if (!SuppressDiagnostic) {

1385 PP.Diag(Tok.getLocation(), diag::err_too_many_args_in_macro_invoc);

1386 SuppressDiagnostic = true;

1387 }

1388 continue;

1389

1390 case tok::l_paren:

1391 ++ParenDepth;

1392 if (Result)

1393 break;

1394 if (!SuppressDiagnostic) {

1395 PP.Diag(Tok.getLocation(), diag::err_pp_nested_paren) << II;

1396 SuppressDiagnostic = true;

1397 }

1398 continue;

1399

1400 case tok::r_paren:

1401 if (--ParenDepth > 0)

1402 continue;

1403

1404

1405

1406 if (Result) {

1407 OS << *Result;

1408

1409

1410 if (*Result > 1)

1411 OS << 'L';

1412 } else {

1413 OS << 0;

1414 if (!SuppressDiagnostic)

1415 PP.Diag(Tok.getLocation(), diag::err_too_few_args_in_macro_invoc);

1416 }

1417 Tok.setKind(tok::numeric_constant);

1418 return;

1419

1420 default: {

1421

1422 if (Result)

1423 break;

1424

1425 bool HasLexedNextToken = false;

1426 Result = Op(Tok, HasLexedNextToken);

1427 ResultTok = Tok;

1428 if (HasLexedNextToken)

1429 goto already_lexed;

1430 continue;

1431 }

1432 }

1433

1434

1435 if (!SuppressDiagnostic) {

1436 if (auto Diag = PP.Diag(Tok.getLocation(), diag::err_pp_expected_after)) {

1438 Diag << LastII;

1439 else

1442 }

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

1444 SuppressDiagnostic = true;

1445 }

1446 }

1447}

1448

1449

1450

1453 signed DiagID) {

1455 if (Tok.isAnnotation() && (II = Tok.getIdentifierInfo()))

1456 return II;

1457

1458 PP.Diag(Tok.getLocation(), DiagID);

1459 return nullptr;

1460}

1461

1462

1464 llvm::Triple Arch(II->getName().lower() + "--");

1465 const llvm::Triple &TT = TI.getTriple();

1466 if (TT.isThumb()) {

1467

1468 if ((Arch.getSubArch() == llvm::Triple::NoSubArch ||

1469 Arch.getSubArch() == TT.getSubArch()) &&

1470 ((TT.getArch() == llvm::Triple::thumb &&

1471 Arch.getArch() == llvm::Triple::arm) ||

1472 (TT.getArch() == llvm::Triple::thumbeb &&

1473 Arch.getArch() == llvm::Triple::armeb)))

1474 return true;

1475 }

1476

1477

1478 return (Arch.getSubArch() == llvm::Triple::NoSubArch ||

1479 Arch.getSubArch() == TT.getSubArch()) &&

1480 Arch.getArch() == TT.getArch();

1481}

1482

1483

1485 StringRef VendorName = TI.getTriple().getVendorName();

1486 if (VendorName.empty())

1487 VendorName = "unknown";

1488 return VendorName.equals_insensitive(II->getName());

1489}

1490

1491

1493 llvm::Triple OS(llvm::Twine("unknown-unknown-") + II->getName().lower());

1494 if (OS.getOS() == llvm::Triple::Darwin) {

1495

1496 return TI.getTriple().isOSDarwin();

1497 }

1498 return TI.getTriple().getOS() == OS.getOS();

1499}

1500

1501

1504 llvm::Triple Env(llvm::Twine("---") + II->getName().lower());

1505

1506

1507 if (Env.getEnvironment() == llvm::Triple::UnknownEnvironment &&

1508 Env.getEnvironmentName() != "unknown")

1509 return false;

1510 return TI.getTriple().getEnvironment() == Env.getEnvironment();

1511}

1512

1513

1515 if (TI.getTriple().isOSDarwin()) {

1517 if (!VariantTriple)

1518 return false;

1519

1520 llvm::Triple OS(llvm::Twine("unknown-unknown-") + II->getName().lower());

1521 if (OS.getOS() == llvm::Triple::Darwin) {

1522

1523 return VariantTriple->isOSDarwin();

1524 }

1525 return VariantTriple->getOS() == OS.getOS();

1526 }

1527 return false;

1528}

1529

1530

1533 if (TI.getTriple().isOSDarwin()) {

1535 if (!VariantTriple)

1536 return false;

1537 llvm::Triple Env(llvm::Twine("---") + II->getName().lower());

1538 return VariantTriple->getEnvironment() == Env.getEnvironment();

1539 }

1540 return false;

1541}

1542

1543#if defined(__sun__) && defined(__svr4__) && defined(__clang__) && \

1544 __clang__ < 20

1545

1546

1547

1548

1549asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"

1550 "RSt8ios_basecPKSt2tmPKcSB_ = "

1551 "_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"

1552 "RSt8ios_basecPK2tmPKcSB_");

1553#endif

1554

1556

1557#define TYPE_TRAIT_1(Spelling, Name, Key) \

1558 case tok::kw_##Spelling: \

1559 return true;

1560#define TYPE_TRAIT_2(Spelling, Name, Key) \

1561 case tok::kw_##Spelling: \

1562 return true;

1563#define TYPE_TRAIT_N(Spelling, Name, Key) \

1564 case tok::kw_##Spelling: \

1565 return true;

1566#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \

1567 case tok::kw_##Spelling: \

1568 return true;

1569#define EXPRESSION_TRAIT(Spelling, Name, Key) \

1570 case tok::kw_##Spelling: \

1571 return true;

1572#define TRANSFORM_TYPE_TRAIT_DEF(K, Spelling) \

1573 case tok::kw___##Spelling: \

1574 return true;

1575

1576 switch (Tok.getKind()) {

1577 default:

1578 return false;

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

1580 }

1581}

1582

1583

1584

1585void Preprocessor::ExpandBuiltinMacro(Token &Tok) {

1586

1588 assert(II && "Can't be a macro without id info!");

1589

1590

1591

1592 if (II == Ident_Pragma)

1593 return Handle_Pragma(Tok);

1594 else if (II == Ident__pragma)

1595 return HandleMicrosoft__pragma(Tok);

1596

1597 ++NumBuiltinMacroExpanded;

1598

1599 SmallString<128> TmpBuffer;

1600 llvm::raw_svector_ostream OS(TmpBuffer);

1601

1602

1607

1608 if (II == Ident__LINE__) {

1609

1610

1611

1613

1614

1615

1617

1618

1619

1620

1621

1622

1623 Loc = SourceMgr.getExpansionRange(Loc).getEnd();

1624 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Loc);

1625

1626

1629 } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__ ||

1630 II == Ident__FILE_NAME__) {

1631

1632

1633 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());

1634

1635

1636

1637 if (II == Ident__BASE_FILE__ && PLoc.isValid()) {

1639 while (NextLoc.isValid()) {

1640 PLoc = SourceMgr.getPresumedLoc(NextLoc);

1642 break;

1643

1645 }

1646 }

1647

1648

1649 SmallString<256> FN;

1651

1652

1653 if (II == Ident__FILE_NAME__) {

1655 } else {

1658 }

1660 OS << '"' << FN << '"';

1661 }

1663 } else if (II == Ident__DATE__) {

1665 if (!DATELoc.isValid())

1672 return;

1673 } else if (II == Ident__TIME__) {

1675 if (!TIMELoc.isValid())

1682 return;

1683 } else if (II == Ident__INCLUDE_LEVEL__) {

1684

1685

1686 unsigned Depth = 0;

1687

1688 PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation());

1690 PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());

1691 for (; PLoc.isValid(); ++Depth)

1692 PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc());

1693 }

1694

1695

1696 OS << Depth;

1698 } else if (II == Ident__TIMESTAMP__) {

1700

1701

1703 std::stringstream TmpStream;

1704 TmpStream.imbue(std::locale("C"));

1707 std::tm *TM = std::gmtime(&TT);

1708 TmpStream << std::put_time(TM, "%a %b %e %T %Y");

1709 } else {

1710

1711

1712 const FileEntry *CurFile = nullptr;

1714 CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID());

1715 if (CurFile) {

1717 struct tm *TM = localtime(&TT);

1718 TmpStream << std::put_time(TM, "%a %b %e %T %Y");

1719 }

1720 }

1721 Result = TmpStream.str();

1723 Result = "??? ??? ?? ??:??:?? ????";

1726 } else if (II == Ident__FLT_EVAL_METHOD__) {

1727

1729

1732

1733

1734 Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);

1736 }

1737 } else if (II == Ident__COUNTER__) {

1739 getLangOpts().C2y ? diag::warn_counter : diag::ext_counter);

1740

1741

1742 constexpr uint32_t MaxPosValue = std::numeric_limits<int32_t>::max();

1743 if (CounterValue > MaxPosValue) {

1745

1746

1747

1748

1749 CounterValue = MaxPosValue;

1750 }

1751 OS << CounterValue++;

1753 } else if (II == Ident__has_feature) {

1755 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1757 diag::err_feature_check_malformed);

1759 });

1760 } else if (II == Ident__has_extension) {

1762 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1764 diag::err_feature_check_malformed);

1766 });

1767 } else if (II == Ident__has_builtin) {

1769 OS, Tok, II, *this, false,

1770 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1772 Tok, *this, diag::err_feature_check_malformed);

1773 if (!II)

1774 return false;

1776 if (BuiltinID != 0) {

1778 case Builtin::BI__builtin_cpu_is:

1780 case Builtin::BI__builtin_cpu_init:

1782 case Builtin::BI__builtin_cpu_supports:

1784 case Builtin::BI__builtin_operator_new:

1785 case Builtin::BI__builtin_operator_delete:

1786

1787

1788 return 201802;

1789 default:

1790

1792 return false;

1796 }

1797 return true;

1799 return true;

1800 } else if (II->getTokenID() != tok::identifier &&

1801 II->getName().starts_with("__builtin_")) {

1802 return true;

1803 } else {

1804 return llvm::StringSwitch(II->getName())

1805

1806#define BuiltinTemplate(BTName) .Case(#BTName, getLangOpts().CPlusPlus)

1807#include "clang/Basic/BuiltinTemplates.inc"

1808

1809

1810

1811 .Case("__is_target_arch", true)

1812 .Case("__is_target_vendor", true)

1813 .Case("__is_target_os", true)

1814 .Case("__is_target_environment", true)

1815 .Case("__is_target_variant_os", true)

1816 .Case("__is_target_variant_environment", true)

1817 .Default(false);

1818 }

1819 });

1820 } else if (II == Ident__has_constexpr_builtin) {

1822 OS, Tok, II, *this, false,

1823 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1825 Tok, *this, diag::err_feature_check_malformed);

1826 if (!II)

1827 return false;

1829 return BuiltinOp != 0 &&

1831 });

1832 } else if (II == Ident__is_identifier) {

1834 [](Token &Tok, bool &HasLexedNextToken) -> int {

1835 return Tok.is(tok::identifier);

1836 });

1837 } else if (II == Ident__has_attribute) {

1839 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1841 diag::err_feature_check_malformed);

1844 : 0;

1845 });

1846 } else if (II == Ident__has_declspec) {

1848 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1850 diag::err_feature_check_malformed);

1851 if (II) {

1852 const LangOptions &LangOpts = getLangOpts();

1853 return LangOpts.DeclSpecKeyword &&

1856 }

1857

1858 return false;

1859 });

1860 } else if (II == Ident__has_cpp_attribute ||

1861 II == Ident__has_c_attribute) {

1862 bool IsCXX = II == Ident__has_cpp_attribute;

1864 [&](Token &Tok, bool &HasLexedNextToken) -> int {

1865 IdentifierInfo *ScopeII = nullptr;

1867 Tok, *this, diag::err_feature_check_malformed);

1868 if (!II)

1869 return false;

1870

1871

1872

1874 if (Tok.isNot(tok::coloncolon))

1875 HasLexedNextToken = true;

1876 else {

1877 ScopeII = II;

1878

1881 diag::err_feature_check_malformed);

1882 }

1883

1889 : 0;

1890 });

1891 } else if (II == Ident__has_include ||

1892 II == Ident__has_include_next) {

1893

1894

1895

1897 if (II == Ident__has_include)

1898 Value = EvaluateHasInclude(Tok, II);

1899 else

1900 Value = EvaluateHasIncludeNext(Tok, II);

1901

1902 if (Tok.isNot(tok::r_paren))

1903 return;

1906 } else if (II == Ident__has_embed) {

1907

1908

1909

1910

1913 return;

1914

1916 OS << static_cast(Value);

1917 } else if (II == Ident__has_warning) {

1918

1920 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1921 std::string WarningName;

1923

1924 HasLexedNextToken = Tok.is(tok::string_literal);

1926 false))

1927 return false;

1928

1929

1930

1931 if (WarningName.size() < 3 || WarningName[0] != '-' ||

1932 WarningName[1] != 'W') {

1933 Diag(StrStartLoc, diag::warn_has_warning_invalid_option);

1934 return false;

1935 }

1936

1937

1938

1939

1940

1941 SmallVector<diag::kind, 10> Diags;

1944 WarningName.substr(2), Diags);

1945 });

1946 } else if (II == Ident__building_module) {

1947

1948

1949

1951 [this](Token &Tok, bool &HasLexedNextToken) -> int {

1953 diag::err_expected_id_building_module);

1956 });

1957 } else if (II == Ident__MODULE__) {

1958

1963 } else if (II == Ident__identifier) {

1965

1966

1967

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

1970

1972 << II << tok::l_paren;

1973

1976 return;

1977 }

1978

1981

1985 StringLiteralParser Literal(Tok, *this,

1988 return;

1989

1992 } else {

1995

1997 return;

1998 }

1999

2000

2001 Token RParen;

2003 if (RParen.isNot(tok::r_paren)) {

2006 Diag(LParenLoc, diag::note_matching) << tok::l_paren;

2007 }

2008 return;

2009 } else if (II == Ident__is_target_arch) {

2011 OS, Tok, II, *this, false,

2012 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2014 Tok, *this, diag::err_feature_check_malformed);

2016 });

2017 } else if (II == Ident__is_target_vendor) {

2019 OS, Tok, II, *this, false,

2020 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2022 Tok, *this, diag::err_feature_check_malformed);

2024 });

2025 } else if (II == Ident__is_target_os) {

2027 OS, Tok, II, *this, false,

2028 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2030 Tok, *this, diag::err_feature_check_malformed);

2032 });

2033 } else if (II == Ident__is_target_environment) {

2035 OS, Tok, II, *this, false,

2036 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2038 Tok, *this, diag::err_feature_check_malformed);

2040 });

2041 } else if (II == Ident__is_target_variant_os) {

2043 OS, Tok, II, *this, false,

2044 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2046 Tok, *this, diag::err_feature_check_malformed);

2048 });

2049 } else if (II == Ident__is_target_variant_environment) {

2051 OS, Tok, II, *this, false,

2052 [this](Token &Tok, bool &HasLexedNextToken) -> int {

2054 Tok, *this, diag::err_feature_check_malformed);

2056 });

2057 } else {

2058 llvm_unreachable("Unknown identifier!");

2059 }

2064}

2065

2073

2077 LangOpts.remapPathPrefix(Path);

2078 if (LangOpts.UseTargetPathSeparator) {

2079 if (TI.getTriple().isOSWindows())

2080 llvm::sys::path::remove_dots(Path, false,

2081 llvm::sys::path::Style::windows_backslash);

2082 else

2083 llvm::sys::path::remove_dots(Path, false, llvm::sys::path::Style::posix);

2084 }

2085}

2086

2091

2092

2093 StringRef PLFileName = llvm::sys::path::filename(PLoc.getFilename());

2094 if (PLFileName.empty())

2096 FileName.append(PLFileName.begin(), PLFileName.end());

2098}

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

static bool getDiagnosticsInGroup(diag::Flavor Flavor, const WarningOption *Group, SmallVectorImpl< diag::kind > &Diags, diag::CustomDiagInfo *CustomDiagInfo)

Return true if any diagnostics were found in this group, even if they were filtered out due to having...

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

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

llvm::MachO::FileType FileType

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

static bool HasExtension(const Preprocessor &PP, StringRef Extension)

HasExtension - Return true if we recognize and implement the feature specified by the identifier,...

Definition PPMacroExpansion.cpp:1108

static bool CheckMatchedBrackets(const SmallVectorImpl< Token > &Tokens)

CheckMatchedBrackets - Returns true if the braces and parentheses in the token vector are properly ne...

Definition PPMacroExpansion.cpp:589

static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, ConstSearchDirIterator LookupFrom, const FileEntry *LookupFromFile)

EvaluateHasIncludeCommon - Process a '__has_include("path")' or '__has_include_next("path")' expressi...

Definition PPMacroExpansion.cpp:1137

Bracket

Definition PPMacroExpansion.cpp:582

@ Paren

Definition PPMacroExpansion.cpp:584

@ Brace

Definition PPMacroExpansion.cpp:583

static bool GenerateNewArgTokens(Preprocessor &PP, SmallVectorImpl< Token > &OldTokens, SmallVectorImpl< Token > &NewTokens, unsigned &NumArgs, SmallVectorImpl< SourceRange > &ParenHints, SmallVectorImpl< SourceRange > &InitLists)

GenerateNewArgTokens - Returns true if OldTokens can be converted to a new vector of tokens in NewTok...

Definition PPMacroExpansion.cpp:618

static bool isTargetVariantOS(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_variant_os builtin macro.

Definition PPMacroExpansion.cpp:1514

static bool isTrivialSingleTokenExpansion(const MacroInfo *MI, const IdentifierInfo *MacroIdent, Preprocessor &PP)

isTrivialSingleTokenExpansion - Return true if MI, which has a single token in its expansion,...

Definition PPMacroExpansion.cpp:391

static bool isTargetArch(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_arch builtin macro.

Definition PPMacroExpansion.cpp:1463

static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, Preprocessor &PP)

ComputeDATE_TIME - Compute the current time, enter it into the specified scratch buffer,...

Definition PPMacroExpansion.cpp:1043

static bool isTargetVariantEnvironment(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_variant_environment builtin macro.

Definition PPMacroExpansion.cpp:1531

static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_environment builtin macro.

Definition PPMacroExpansion.cpp:1502

static bool IsBuiltinTrait(Token &Tok)

Definition PPMacroExpansion.cpp:1555

static bool isTargetOS(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_os builtin macro.

Definition PPMacroExpansion.cpp:1492

static bool isTargetVendor(const TargetInfo &TI, const IdentifierInfo *II)

Implements the __is_target_vendor builtin macro.

Definition PPMacroExpansion.cpp:1484

static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream &OS, Token &Tok, IdentifierInfo *II, Preprocessor &PP, bool ExpandArgs, llvm::function_ref< int(Token &Tok, bool &HasLexedNextTok)> Op)

Process single-argument builtin feature-like macros that return integer values.

Definition PPMacroExpansion.cpp:1341

static bool HasFeature(const Preprocessor &PP, StringRef Feature)

HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...

Definition PPMacroExpansion.cpp:1090

static IdentifierInfo * ExpectFeatureIdentifierInfo(Token &Tok, Preprocessor &PP, signed DiagID)

Helper function to return the IdentifierInfo structure of a Token or generate a diagnostic if none av...

Definition PPMacroExpansion.cpp:1451

Defines the PreprocessorLexer interface.

Defines the clang::Preprocessor interface.

Defines the clang::SourceLocation class and associated facilities.

Syntax

The style used to specify an attribute.

@ AS_Declspec

__declspec(...)

bool isConstantEvaluated(unsigned ID) const

Return true if this function can be constant evaluated by Clang frontend.

diag::Severity getExtensionHandlingBehavior() const

const IntrusiveRefCntPtr< DiagnosticIDs > & getDiagnosticIDs() const

virtual void updateOutOfDateIdentifier(const IdentifierInfo &II)=0

Update an out-of-date identifier.

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

time_t getModificationTime() const

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.

unsigned getBuiltinID() const

Return a value indicating whether this is a builtin function.

tok::TokenKind getTokenID() const

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

bool hadMacroDefinition() const

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

bool isFromAST() const

Return true if the identifier in its current state was loaded from an AST file.

const char * getNameStart() const

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

void setHasMacroDefinition(bool Val)

bool isOutOfDate() const

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

void setChangedSinceDeserialization()

Note that this identifier has changed since it was loaded from an AST file.

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

Are we compiling a module?

std::string CurrentModule

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

static std::string Stringify(StringRef Str, bool Charify=false)

Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...

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

static MacroArgs * create(const MacroInfo *MI, ArrayRef< Token > UnexpArgTokens, bool VarargsElided, Preprocessor &PP)

MacroArgs ctor function - Create a new MacroArgs object with the specified macro and argument info.

void destroy(Preprocessor &PP)

destroy - Destroy and deallocate the memory for this object.

A description of the current definition of a macro.

MacroInfo * getMacroInfo() const

Get the MacroInfo that should be used for this definition.

bool isAmbiguous() const

true if the definition is ambiguous, false otherwise.

void forAllDefinitions(Fn F) const

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

const MacroDirective * getPrevious() const

Get previous definition of the macro with the same name.

void setPrevious(MacroDirective *Prev)

Set previous definition of the macro with the same name.

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

ArrayRef< const IdentifierInfo * > params() const

unsigned getNumTokens() const

Return the number of tokens that this macro expands to.

unsigned getNumParams() const

const Token & getReplacementToken(unsigned Tok) const

bool isBuiltinMacro() const

Return true if this macro requires processing before expansion.

SourceLocation getDefinitionLoc() const

Return the location that the macro was defined at.

bool hasCommaPasting() const

bool isObjectLike() const

bool isWarnIfUnused() const

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

bool isEnabled() const

Return true if this macro is enabled.

void setIsUsed(bool Val)

Set the value of the IsUsed flag.

Represents a macro directive exported by a module.

static ModuleMacro * create(Preprocessor &PP, Module *OwningModule, const IdentifierInfo *II, MacroInfo *Macro, ArrayRef< ModuleMacro * > Overrides)

void Profile(llvm::FoldingSetNodeID &ID) const

Describes a module or submodule.

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

OptionalFileEntryRef getFileEntry() const

getFileEntry - Return the FileEntry corresponding to this FileID.

std::optional< uint64_t > SourceDateEpoch

If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.

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

SourceLocation getLastFPEvalPragmaLocation() const

bool FinishLexStringLiteral(Token &Result, std::string &String, const char *DiagnosticTag, bool AllowMacroExpansion)

Complete the lexing of a string literal where the first token has already been lexed (see LexStringLi...

void dumpMacroInfo(const IdentifierInfo *II)

Definition PPMacroExpansion.cpp:256

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

Register an exported macro for a module and identifier.

Definition PPMacroExpansion.cpp:130

void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED, MacroDirective *MD)

Set a MacroDirective that was loaded from a PCH file.

Definition PPMacroExpansion.cpp:94

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

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

PPCallbacks * getPPCallbacks() const

const MacroInfo * getMacroInfo(const IdentifierInfo *II) const

void CreateString(StringRef Str, Token &Tok, SourceLocation ExpansionLocStart=SourceLocation(), SourceLocation ExpansionLocEnd=SourceLocation())

Plop the specified string into a scratch buffer and set the specified token's location and length to ...

void markMacroAsUsed(MacroInfo *MI)

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

Definition PPMacroExpansion.cpp:2066

MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const

Given an identifier, return the latest non-imported macro directive for that identifier.

Definition PPMacroExpansion.cpp:61

void Lex(Token &Result)

Lex the next token for this preprocessor.

bool isParsingIfOrElifDirective() const

True if we are currently preprocessing a if or elif directive.

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.

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

static void processPathToFileName(SmallVectorImpl< char > &FileName, const PresumedLoc &PLoc, const LangOptions &LangOpts, const TargetInfo &TI)

Definition PPMacroExpansion.cpp:2087

const TargetInfo & getTargetInfo() const

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

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

void LexUnexpandedToken(Token &Result)

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

ModuleMacro * getModuleMacro(Module *Mod, const IdentifierInfo *II)

Definition PPMacroExpansion.cpp:169

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.

PreprocessorLexer * getCurrentFileLexer() const

Return the current file lexer being lexed from.

HeaderSearch & getHeaderSearchInfo() const

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

ExternalPreprocessorSource * getExternalSource() const

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.

Builtin::Context & getBuiltinInfo()

const PreprocessorOptions & getPreprocessorOpts() const

Retrieve the preprocessor options used to initialize this preprocessor.

LangOptions::FPEvalMethodKind getTUFPEvalMethod() const

const LangOptions & getLangOpts() const

static void processPathForFileMacro(SmallVectorImpl< char > &Path, const LangOptions &LangOpts, const TargetInfo &TI)

Definition PPMacroExpansion.cpp:2074

DiagnosticsEngine & getDiagnostics() const

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Computes the source location just past the end of the token at this source location.

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

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

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

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

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const

Forwarding function for diagnostics.

void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD)

Add a directive to the macro directive history for this identifier.

Definition PPMacroExpansion.cpp:69

Represents an unpacked "presumed" location which can be presented to the user.

const char * getFilename() const

Return the presumed filename of this location.

unsigned getLine() const

Return the presumed line number of this location.

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.

A trivial tuple used to represent a source range.

Exposes information about the current target.

virtual bool supportsCpuSupports() const

virtual bool supportsCpuInit() const

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

const llvm::Triple * getDarwinTargetVariantTriple() const

Returns the darwin target variant triple, the variant of the deployment target for which the code is ...

virtual bool supportsCpuIs() const

TokenLexer - This implements a lexer that returns tokens from a macro body or token stream instead of...

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

IdentifierInfo * getIdentifierInfo() const

unsigned getFlags() const

Return the internal represtation of the flags.

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 setLength(unsigned Len)

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.

void setLocation(SourceLocation L)

bool isNot(tok::TokenKind K) const

bool isAnnotation() const

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

bool hasUDSuffix() const

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

void startToken()

Reset all flags to cleared.

void setIdentifierInfo(IdentifierInfo *II)

void setFlagValue(TokenFlags Flag, bool Val)

Set a flag to either true or false.

void setFlag(TokenFlags Flag)

Set the specified flag.

unsigned getGeneration() const

Get the current visibility generation.

Defines the clang::TargetInfo interface.

bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)

Returns true if the required target features of a builtin function are enabled.

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.

@ WarningOrError

A diagnostic that indicates a problem or potential problem.

@ Error

Present this diagnostic as an error.

@ OS

Indicates that the tracking object is a descendant of a referenced-counted OSObject,...

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

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

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

detail::SearchDirIteratorImpl< true > ConstSearchDirIterator

nullptr

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

@ Result

The result type of a method or function.

@ Braces

New-expression has a C++11 list-initializer.