clang: lib/Basic/IdentifierTable.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

22#include "llvm/ADT/DenseMapInfo.h"

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

24#include "llvm/ADT/StringMap.h"

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

26#include "llvm/Support/Allocator.h"

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

28#include

29#include

30#include

31#include

32

33using namespace clang;

34

35

36

37

39 "Insufficient ObjCOrBuiltinID Bits");

40

41

42

43

44

46

48

49namespace {

50

51

52

54public:

55 StringRef Next() override { return StringRef(); }

56};

57

58}

59

61 return new EmptyLookupIterator();

62}

63

65 : HashTable(8192),

66 ExternalLookup(ExternalLookup) {}

67

75

76

77

78

79

80

81

82

83

84

85

88

89

90 assert((Flag & ~(Flag - 1)) == Flag && "Multiple bits set?");

91

92 switch (Flag) {

94 if (LangOpts.C99)

98 if (LangOpts.C23)

104 if (LangOpts.CPlusPlus11)

108 if (LangOpts.CPlusPlus20)

116 if (LangOpts.Bool) return KS_Enabled;

123 return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ? KS_Enabled

130 if (LangOpts.Char8) return KS_Enabled;

131 if (LangOpts.CPlusPlus20) return KS_Unknown;

132 if (LangOpts.CPlusPlus) return KS_Future;

135

136

157

158

163

169 default:

170 llvm_unreachable("Unknown KeywordStatus flag");

171 }

172}

173

175 unsigned Flags) {

176

178

179

181 if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&

184 if (LangOpts.ZOSExt && (Flags & KEYNOZOS))

187

188 while (Flags != 0) {

189 unsigned CurFlag = Flags & ~(Flags - 1);

190 Flags = Flags & ~CurFlag;

191 CurStatus = std::max(

192 CurStatus,

194 }

195

198 return CurStatus;

199}

200

205

207 StringRef Name) {

211}

212

213

214

215

220

221

222

224

225

226

227

228

231 return;

232 }

233

235 Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);

238}

239

240

241

248

249

250

256

260

261 if (BTID != tok::not_notable) {

264 }

265}

266

267

268

270

271#define KEYWORD(NAME, FLAGS) \

272 AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \

273 FLAGS, LangOpts, *this);

274#define ALIAS(NAME, TOK, FLAGS) \

275 AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \

276 FLAGS, LangOpts, *this);

277#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \

278 if (LangOpts.CXXOperatorNames) \

279 AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); \

280 else \

281 MarkIdentifierAsKeywordInCpp(*this, StringRef(#NAME));

282#define OBJC_AT_KEYWORD(NAME) \

283 if (LangOpts.ObjC) \

284 AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);

285#define NOTABLE_IDENTIFIER(NAME) \

286 AddNotableIdentifier(StringRef(#NAME), tok::NAME, *this);

287

288#define TESTING_KEYWORD(NAME, FLAGS)

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

290

291 if (LangOpts.ParseUnknownAnytype)

292 AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,

293 LangOpts, *this);

294

295 if (LangOpts.DeclSpecKeyword)

296 AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);

297

298 if (LangOpts.IEEE128)

299 AddKeyword("__ieee128", tok::kw___float128, KEYALL, LangOpts, *this);

300

301

303}

304

305

306

307

310 switch (K) {

311#define KEYWORD(NAME, FLAGS) \

312 case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);

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

315 }

316}

317

318

319

324 return true;

325 default:

326 return false;

327 }

328}

329

330

331

333 if (!LangOpts.CPlusPlus || isKeyword(LangOpts))

334 return false;

335

336

338 LangOptsNoCPP.CPlusPlus = false;

339 LangOptsNoCPP.CPlusPlus11 = false;

340 LangOptsNoCPP.CPlusPlus20 = false;

341 return isKeyword(LangOptsNoCPP);

342}

343

346 StringRef Name = getName();

347

348

349

350 if (Name.size() <= 1)

352

353

354 if (Name[0] == '_') {

355

356

357

358 if (Name[1] == '_')

360

361 if ('A' <= Name[1] && Name[1] <= 'Z')

362 return ReservedIdentifierStatus::

363 StartsWithUnderscoreFollowedByCapitalLetter;

364

365

366

368 }

369

370

371 if (LangOpts.CPlusPlus && Name.contains("__"))

373

375}

376

379 StringRef Name = getName();

380

381

382

383

384 if (Name[0] != '_')

386

387 if (Name.contains("__"))

389

391}

392

394 StringRef Name = getName();

395 if (Name.size() >= 2 && Name.front() == '_' &&

396 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))

397 return Name.ltrim('_');

398 return Name;

399}

400

402

403

404

405

406

407#define HASH(LEN, FIRST, THIRD) \

408 (LEN << 6) + (((FIRST - 'a') - (THIRD - 'a')) & 63)

409#define CASE(LEN, FIRST, THIRD, NAME) \

410 case HASH(LEN, FIRST, THIRD): \

411 return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME

412

414 if (Len < 2) return tok::pp_not_keyword;

416 switch (HASH(Len, Name[0], Name[2])) {

417 default: return tok::pp_not_keyword;

418 CASE( 2, 'i', '\0', if);

419 CASE( 4, 'e', 'i', elif);

420 CASE( 4, 'e', 's', else);

421 CASE( 4, 'l', 'n', line);

422 CASE( 4, 's', 'c', sccs);

423 CASE( 5, 'e', 'b', embed);

424 CASE( 5, 'e', 'd', endif);

425 CASE( 5, 'e', 'r', error);

426 CASE( 5, 'i', 'e', ident);

427 CASE( 5, 'i', 'd', ifdef);

428 CASE( 5, 'u', 'd', undef);

429

430 CASE( 6, 'a', 's', assert);

431 CASE( 6, 'd', 'f', define);

432 CASE( 6, 'i', 'n', ifndef);

433 CASE( 6, 'i', 'p', import);

434 CASE( 6, 'p', 'a', pragma);

435

436 CASE( 7, 'd', 'f', defined);

437 CASE( 7, 'e', 'i', elifdef);

438 CASE( 7, 'i', 'c', include);

439 CASE( 7, 'w', 'r', warning);

440

441 CASE( 8, 'e', 'i', elifndef);

442 CASE( 8, 'u', 'a', unassert);

443 CASE(12, 'i', 'c', include_next);

444

445 CASE(14, '_', 'p', __public_macro);

446

447 CASE(15, '_', 'p', __private_macro);

448

449 CASE(16, '_', 'i', __include_macros);

450#undef CASE

451#undef HASH

452 }

453}

454

455

456

457

458

459

460

462 unsigned NumBuckets = HashTable.getNumBuckets();

463 unsigned NumIdentifiers = HashTable.getNumItems();

464 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;

465 unsigned AverageIdentifierSize = 0;

466 unsigned MaxIdentifierLength = 0;

467

468

469 for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator

470 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {

471 unsigned IdLen = I->getKeyLength();

472 AverageIdentifierSize += IdLen;

473 if (MaxIdentifierLength < IdLen)

474 MaxIdentifierLength = IdLen;

475 }

476

477 fprintf(stderr, "\n*** Identifier Table Stats:\n");

478 fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers);

479 fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);

480 fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",

481 NumIdentifiers/(double)NumBuckets);

482 fprintf(stderr, "Ave identifier length: %f\n",

483 (AverageIdentifierSize/(double)NumIdentifiers));

484 fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);

485

486

487 HashTable.getAllocator().PrintStats();

488}

489

490

491

492

493

497

499 assert(!Names.empty() && "must have >= 1 selector slots");

501 return false;

502 for (unsigned I = 0, E = Names.size(); I != E; ++I) {

504 return false;

505 }

506 return true;

507}

508

512

514 unsigned IIF = getIdentifierInfoFlag();

515 if (IIF <= ZeroArg)

516 return 0;

517 if (IIF == OneArg)

518 return 1;

519

522}

523

526 if (getIdentifierInfoFlag() < MultiArg) {

527 assert(argIndex == 0 && "illegal keyword index");

528 return getAsIdentifierInfo();

529 }

530

531

534}

535

538 return II ? II->getName() : StringRef();

539}

540

543 llvm::raw_svector_ostream OS(Str);

545 if (*I)

546 OS << (*I)->getName();

547 OS << ':';

548 }

549

550 return std::string(OS.str());

551}

552

555 return "";

556

557 if (getIdentifierInfoFlag() < MultiArg) {

559

561 assert(II && "If the number of arguments is 0 then II is guaranteed to "

562 "not be null.");

563 return std::string(II->getName());

564 }

565

566 if (!II)

567 return ":";

568

569 return II->getName().str() + ":";

570 }

571

572

573 return getMultiKeywordSelector()->getName();

574}

575

579

581

582

583

584

586 if (name.size() < word.size()) return false;

587 return ((name.size() == word.size() || isLowercase(name[word.size()])) &&

588 name.starts_with(word));

589}

590

594

598 if (name == "dealloc") return OMF_dealloc;

600 if (name == "release") return OMF_release;

601 if (name == "retain") return OMF_retain;

603 if (name == "self") return OMF_self;

605 }

606

607 if (name == "performSelector" || name == "performSelectorInBackground" ||

608 name == "performSelectorOnMainThread")

610

611

613

615 switch (name.front()) {

616 case 'a':

618 break;

619 case 'c':

621 break;

622 case 'i':

624 break;

625 case 'm':

627 break;

628 case 'n':

630 break;

631 default:

632 break;

633 }

634

636}

637

641

642 StringRef name = first->getName();

643

644 if (name.empty()) return OIT_None;

645 switch (name.front()) {

646 case 'a':

648 break;

649 case 'd':

652 break;

653 case 's':

656 break;

657 case 'i':

659 break;

660 default:

661 break;

662 }

664}

665

669

670 StringRef name = first->getName();

671

672 switch (name.front()) {

673 case 'a':

674 if (name == "appendFormat") return SFF_NSString;

675 break;

676

677 case 'i':

678 if (name == "initWithFormat") return SFF_NSString;

679 break;

680

681 case 'l':

682 if (name == "localizedStringWithFormat") return SFF_NSString;

683 break;

684

685 case 's':

686 if (name == "stringByAppendingFormat" ||

687 name == "stringWithFormat") return SFF_NSString;

688 break;

689 }

691}

692

693namespace {

694

695struct SelectorTableImpl {

696 llvm::FoldingSet Table;

697 llvm::BumpPtrAllocator Allocator;

698};

699

700}

701

703 return *static_cast<SelectorTableImpl*>(P);

704}

705

709 SetterName += Name;

710 SetterName[3] = toUppercase(SetterName[3]);

711 return SetterName;

712}

713

722

725 assert(Name.starts_with("set") && "invalid setter name");

726 return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();

727}

728

731 return SelTabImpl.Allocator.getTotalMemory();

732}

733

736 if (nKeys < 2)

737 return Selector(IIV[0], nKeys);

738

740

741

742 llvm::FoldingSetNodeID ID;

744

745 void *InsertPos = nullptr;

747 SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))

749

750

751

757 SelTabImpl.Table.InsertNode(SI, InsertPos);

759}

760

762 Impl = new SelectorTableImpl();

763}

764

768

770 switch (Operator) {

773 return nullptr;

774

775#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \

776 case OO_##Name: return Spelling;

777#include "clang/Basic/OperatorKinds.def"

778 }

779

780 llvm_unreachable("Invalid OverloadedOperatorKind!");

781}

782

784 bool isContextSensitive) {

785 switch (kind) {

787 return isContextSensitive ? "nonnull" : "_Nonnull";

788

790 return isContextSensitive ? "nullable" : "_Nullable";

791

793 assert(!isContextSensitive &&

794 "_Nullable_result isn't supported as context-sensitive keyword");

795 return "_Nullable_result";

796

798 return isContextSensitive ? "null_unspecified" : "_Null_unspecified";

799 }

800 llvm_unreachable("Unknown nullability kind.");

801}

802

805 switch (NK) {

807 return OS << "NonNull";

809 return OS << "Nullable";

811 return OS << "NullableResult";

813 return OS << "Unspecified";

814 }

815 llvm_unreachable("Unknown nullability kind.");

816}

817

822

823 unsigned Flags = llvm::StringSwitch(II.getName())

824#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)

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

826#undef KEYWORD

827 ;

828

829 if (LangOpts.CPlusPlus) {

831 return diag::warn_cxx11_keyword;

832

833

834

835

838 return diag::warn_cxx20_keyword;

839 } else {

841 return diag::warn_c99_keyword;

843 return diag::warn_c23_keyword;

844 }

845

846 llvm_unreachable(

847 "Keyword not known to come from a newer Standard or proposed Standard");

848}

FormatToken * Next

The next token in the unwrapped line.

static void AddObjCKeyword(StringRef Name, tok::ObjCKeywordKind ObjCID, IdentifierTable &Table)

AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or "property".

Definition IdentifierTable.cpp:251

static bool IsKeywordInCpp(unsigned Flags)

Definition IdentifierTable.cpp:201

static void AddCXXOperatorKeyword(StringRef Keyword, tok::TokenKind TokenCode, IdentifierTable &Table)

AddCXXOperatorKeyword - Register a C++ operator keyword alternative representations.

Definition IdentifierTable.cpp:242

static void AddNotableIdentifier(StringRef Name, tok::NotableIdentifierKind BTID, IdentifierTable &Table)

Definition IdentifierTable.cpp:257

static void MarkIdentifierAsKeywordInCpp(IdentifierTable &Table, StringRef Name)

Definition IdentifierTable.cpp:206

static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts, TokenKey Flag)

Definition IdentifierTable.cpp:86

static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, tok::TokenKind K)

Checks if the specified token kind represents a keyword in the specified language.

Definition IdentifierTable.cpp:308

static bool startsWithWord(StringRef name, StringRef word)

Interpreting the given string using the normal CamelCase conventions, determine whether the given str...

Definition IdentifierTable.cpp:585

#define CASE(LEN, FIRST, THIRD, NAME)

static void AddKeyword(StringRef Keyword, tok::TokenKind TokenCode, unsigned Flags, const LangOptions &LangOpts, IdentifierTable &Table)

AddKeyword - This method is used to associate a token ID with specific identifiers because they are l...

Definition IdentifierTable.cpp:216

static SelectorTableImpl & getSelectorTableImpl(void *P)

Definition IdentifierTable.cpp:702

#define HASH(LEN, FIRST, THIRD)

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

Defines the clang::LangOptions interface.

Defines an enumeration for C++ overloaded operators.

Defines various enumerations that describe declaration and type specifiers.

Enumerates target-specific builtins in their own namespaces within namespace clang.

Defines the clang::TokenKind enum and support functions.

Provides lookups to, and iteration over, IdentiferInfo objects.

virtual ~IdentifierInfoLookup()

virtual IdentifierIterator * getIdentifiers()

Retrieve an iterator into the set of all identifiers known to this identifier lookup source.

Definition IdentifierTable.cpp:60

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

bool isCPlusPlusKeyword(const LangOptions &LangOpts) const

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

Definition IdentifierTable.cpp:332

unsigned getLength() const

Efficiently return the length of this identifier info.

void setModulesImport(bool I)

Set whether this identifier is the contextual keyword import.

void setNotableIdentifierID(unsigned ID)

void setIsExtensionToken(bool Val)

tok::PPKeywordKind getPPKeywordID() const

Return the preprocessor keyword ID for this identifier.

Definition IdentifierTable.cpp:401

tok::TokenKind getTokenID() const

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

void setObjCKeywordID(tok::ObjCKeywordKind ID)

void setHandleIdentifierCase(bool Val=true)

void setIsKeywordInCPlusPlus(bool Val=true)

const char * getNameStart() const

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

bool isKeyword(const LangOptions &LangOpts) const

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

Definition IdentifierTable.cpp:320

ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const

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

Definition IdentifierTable.cpp:345

void setIsCPlusPlusOperatorKeyword(bool Val=true)

isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...

ReservedLiteralSuffixIdStatus isReservedLiteralSuffixId() const

Determine whether this is a name reserved for future standardization or the implementation (C++ [usrl...

Definition IdentifierTable.cpp:378

void setIsFutureCompatKeyword(bool Val)

StringRef deuglifiedName() const

If the identifier is an "uglified" reserved name, return a cleaned form.

Definition IdentifierTable.cpp:393

StringRef getName() const

Return the actual identifier string.

bool isFutureCompatKeyword() const

is/setIsFutureCompatKeyword - Initialize information about whether or not this language token is a ke...

An iterator that walks over all of the known identifiers in the lookup table.

virtual ~IdentifierIterator()

Implements an efficient mapping from strings to IdentifierInfo nodes.

IdentifierTable(IdentifierInfoLookup *ExternalLookup=nullptr)

Create the identifier table.

Definition IdentifierTable.cpp:64

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

void PrintStats() const

Print some statistics to stderr that indicate how well the hashing is doing.

Definition IdentifierTable.cpp:461

void AddKeywords(const LangOptions &LangOpts)

Populate the identifier table with info about the language keywords for the language specified by Lan...

Definition IdentifierTable.cpp:269

diag::kind getFutureCompatDiagKind(const IdentifierInfo &II, const LangOptions &LangOpts)

Returns the correct diagnostic to issue for a future-compat diagnostic warning.

Definition IdentifierTable.cpp:819

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

bool isCompatibleWithMSVC() const

One of these variable length records is kept for each selector containing more than one keyword.

keyword_iterator keyword_end() const

const IdentifierInfo *const * keyword_iterator

std::string getName() const

Definition IdentifierTable.cpp:541

static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs)

keyword_iterator keyword_begin() const

const IdentifierInfo * getIdentifierInfoForSlot(unsigned i) const

~SelectorTable()

Definition IdentifierTable.cpp:765

static std::string getPropertyNameFromSetterSelector(Selector Sel)

Return the property name for the given setter selector.

Definition IdentifierTable.cpp:723

static Selector constructSetterSelector(IdentifierTable &Idents, SelectorTable &SelTable, const IdentifierInfo *Name)

Return the default setter selector for the given identifier.

Definition IdentifierTable.cpp:715

size_t getTotalMemory() const

Return the total amount of memory allocated for managing selectors.

Definition IdentifierTable.cpp:729

Selector getSelector(unsigned NumArgs, const IdentifierInfo **IIV)

Can create any sort of selector.

Definition IdentifierTable.cpp:734

Selector getUnarySelector(const IdentifierInfo *ID)

static SmallString< 64 > constructSetterName(StringRef Name)

Return the default setter name for the given identifier.

Definition IdentifierTable.cpp:707

SelectorTable()

Definition IdentifierTable.cpp:761

Smart pointer class that efficiently represents Objective-C method names.

StringRef getNameForSlot(unsigned argIndex) const

Retrieve the name at a given position in the selector.

Definition IdentifierTable.cpp:536

const IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const

Retrieve the identifier at a given position in the selector.

Definition IdentifierTable.cpp:525

std::string getAsString() const

Derive the full selector name (e.g.

Definition IdentifierTable.cpp:553

void print(llvm::raw_ostream &OS) const

Prints the full selector name (e.g. "foo:bar:").

Definition IdentifierTable.cpp:576

void * getAsOpaquePtr() const

bool isKeywordSelector() const

void dump() const

Definition IdentifierTable.cpp:580

static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel)

Definition IdentifierTable.cpp:638

bool isUnarySelector() const

bool isNull() const

Determine whether this is the empty selector.

unsigned getNumArgs() const

Definition IdentifierTable.cpp:513

unsigned kind

All of the diagnostics that can be emitted by the frontend.

NotableIdentifierKind

Provides a namespace for notable identifers such as float_t and double_t.

ObjCKeywordKind

Provides a namespace for Objective-C keywords which start with an '@'.

TokenKind

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

PPKeywordKind

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

RangeSelector name(std::string ID)

Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...

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

TokenKey

Constants for TokenKinds.def.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

@ OO_None

Not an overloaded operator.

@ NUM_OVERLOADED_OPERATORS

KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags)

Translates flags as specified in TokenKinds.def into keyword status in the given language standard.

Definition IdentifierTable.cpp:174

NullabilityKind

Describes the nullability of a particular type.

@ Nullable

Values of this type can be null.

@ Unspecified

Whether values of this type can be null is (explicitly) unspecified.

@ NonNull

Values of this type can never be null.

LLVM_READONLY char toLowercase(char c)

Converts the given ASCII character to its lowercase equivalent.

ObjCMethodFamily

A family of Objective-C methods.

@ OMF_None

No particular method family.

llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)

Retrieve the spelling of the given nullability kind.

Definition IdentifierTable.cpp:783

ObjCInstanceTypeFamily

A family of Objective-C methods.

ReservedLiteralSuffixIdStatus

@ NotStartsWithUnderscore

@ ContainsDoubleUnderscore

LLVM_READONLY bool isLowercase(unsigned char c)

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

LLVM_READONLY char toUppercase(char c)

Converts the given ASCII character to its uppercase equivalent.

@ Keyword

The name has been typo-corrected to a keyword.

static constexpr int InterestingIdentifierBits

KeywordStatus

How a keyword is treated in the selected standard.

static constexpr uint64_t LargestBuiltinID

const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)

Insertion operator for diagnostics.

const char * getOperatorSpelling(OverloadedOperatorKind Operator)

Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.

Definition IdentifierTable.cpp:769

@ StartsWithDoubleUnderscore

@ ContainsDoubleUnderscore

@ StartsWithUnderscoreAtGlobalScope

__LIBC_ATTRS FILE * stderr