clang 17.0.0git
IdentifierTable.h
Go to the documentation of this file.
1//===- IdentifierTable.h - Hash table for identifier lookup -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the clang::IdentifierInfo, clang::IdentifierTable, and
11/// clang::Selector interfaces.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
16#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
17
19#include "clang/Basic/LLVM.h"
21#include "llvm/ADT/DenseMapInfo.h"
22#include "llvm/ADT/SmallString.h"
23#include "llvm/ADT/StringMap.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Support/Allocator.h"
26#include "llvm/Support/PointerLikeTypeTraits.h"
27#include "llvm/Support/type_traits.h"
28#include <cassert>
29#include <cstddef>
30#include <cstdint>
31#include <cstring>
32#include <string>
33#include <utility>
34
35namespace clang {
36
37class DeclarationName;
38class DeclarationNameTable;
39class IdentifierInfo;
40class LangOptions;
41class MultiKeywordSelector;
42class SourceLocation;
43
45 NotReserved = 0,
51};
52
53/// Determine whether an identifier is reserved for use as a name at global
54/// scope. Such identifiers might be implementation-specific global functions
55/// or variables.
58}
59
60/// Determine whether an identifier is reserved in all contexts. Such
61/// identifiers might be implementation-specific keywords or macros, for
62/// example.
67}
68
69/// A simple pair of identifier info and location.
70using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
71
72/// IdentifierInfo and other related classes are aligned to
73/// 8 bytes so that DeclarationName can use the lower 3 bits
74/// of a pointer to one of these classes.
76
77static constexpr int ObjCOrBuiltinIDBits = 16;
78
79/// One of these records is kept for each identifier that
80/// is lexed. This contains information about whether the token was \#define'd,
81/// is a language keyword, or if it is a front-end token of some sort (e.g. a
82/// variable or function name). The preprocessor keeps this information in a
83/// set, and all tok::identifier tokens have a pointer to one of these.
84/// It is aligned to 8 bytes because DeclarationName needs the lower 3 bits.
85class alignas(IdentifierInfoAlignment) IdentifierInfo {
86 friend class IdentifierTable;
87
88 // Front-end token ID or tok::identifier.
89 unsigned TokenID : 9;
90
91 // ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
92 // First NUM_OBJC_KEYWORDS values are for Objective-C,
93 // the remaining values are for builtins.
94 unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits;
95
96 // True if there is a #define for this.
97 unsigned HasMacro : 1;
98
99 // True if there was a #define for this.
100 unsigned HadMacro : 1;
101
102 // True if the identifier is a language extension.
103 unsigned IsExtension : 1;
104
105 // True if the identifier is a keyword in a newer or proposed Standard.
106 unsigned IsFutureCompatKeyword : 1;
107
108 // True if the identifier is poisoned.
109 unsigned IsPoisoned : 1;
110
111 // True if the identifier is a C++ operator keyword.
112 unsigned IsCPPOperatorKeyword : 1;
113
114 // Internal bit set by the member function RecomputeNeedsHandleIdentifier.
115 // See comment about RecomputeNeedsHandleIdentifier for more info.
116 unsigned NeedsHandleIdentifier : 1;
117
118 // True if the identifier was loaded (at least partially) from an AST file.
119 unsigned IsFromAST : 1;
120
121 // True if the identifier has changed from the definition
122 // loaded from an AST file.
123 unsigned ChangedAfterLoad : 1;
124
125 // True if the identifier's frontend information has changed from the
126 // definition loaded from an AST file.
127 unsigned FEChangedAfterLoad : 1;
128
129 // True if revertTokenIDToIdentifier was called.
130 unsigned RevertedTokenID : 1;
131
132 // True if there may be additional information about
133 // this identifier stored externally.
134 unsigned OutOfDate : 1;
135
136 // True if this is the 'import' contextual keyword.
137 unsigned IsModulesImport : 1;
138
139 // True if this is a mangled OpenMP variant name.
140 unsigned IsMangledOpenMPVariantName : 1;
141
142 // True if this is a deprecated macro.
143 unsigned IsDeprecatedMacro : 1;
144
145 // True if this macro is unsafe in headers.
146 unsigned IsRestrictExpansion : 1;
147
148 // True if this macro is final.
149 unsigned IsFinal : 1;
150
151 // 22 bits left in a 64-bit word.
152
153 // Managed by the language front-end.
154 void *FETokenInfo = nullptr;
155
156 llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr;
157
159 : TokenID(tok::identifier), ObjCOrBuiltinID(0), HasMacro(false),
160 HadMacro(false), IsExtension(false), IsFutureCompatKeyword(false),
161 IsPoisoned(false), IsCPPOperatorKeyword(false),
162 NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false),
163 FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false),
164 IsModulesImport(false), IsMangledOpenMPVariantName(false),
165 IsDeprecatedMacro(false), IsRestrictExpansion(false), IsFinal(false) {}
166
167public:
172
173 /// Return true if this is the identifier for the specified string.
174 ///
175 /// This is intended to be used for string literals only: II->isStr("foo").
176 template <std::size_t StrLen>
177 bool isStr(const char (&Str)[StrLen]) const {
178 return getLength() == StrLen-1 &&
179 memcmp(getNameStart(), Str, StrLen-1) == 0;
180 }
181
182 /// Return true if this is the identifier for the specified StringRef.
183 bool isStr(llvm::StringRef Str) const {
184 llvm::StringRef ThisStr(getNameStart(), getLength());
185 return ThisStr == Str;
186 }
187
188 /// Return the beginning of the actual null-terminated string for this
189 /// identifier.
190 const char *getNameStart() const { return Entry->getKeyData(); }
191
192 /// Efficiently return the length of this identifier info.
193 unsigned getLength() const { return Entry->getKeyLength(); }
194
195 /// Return the actual identifier string.
196 StringRef getName() const {
197 return StringRef(getNameStart(), getLength());
198 }
199
200 /// Return true if this identifier is \#defined to some other value.
201 /// \note The current definition may be in a module and not currently visible.
202 bool hasMacroDefinition() const {
203 return HasMacro;
204 }
205 void setHasMacroDefinition(bool Val) {
206 if (HasMacro == Val) return;
207
208 HasMacro = Val;
209 if (Val) {
210 NeedsHandleIdentifier = true;
211 HadMacro = true;
212 } else {
213 // If this is a final macro, make the deprecation and header unsafe bits
214 // stick around after the undefinition so they apply to any redefinitions.
215 if (!IsFinal) {
216 // Because calling the setters of these calls recomputes, just set them
217 // manually to avoid recomputing a bunch of times.
218 IsDeprecatedMacro = false;
219 IsRestrictExpansion = false;
220 }
221 RecomputeNeedsHandleIdentifier();
222 }
223 }
224 /// Returns true if this identifier was \#defined to some value at any
225 /// moment. In this case there should be an entry for the identifier in the
226 /// macro history table in Preprocessor.
227 bool hadMacroDefinition() const {
228 return HadMacro;
229 }
230
231 bool isDeprecatedMacro() const { return IsDeprecatedMacro; }
232
233 void setIsDeprecatedMacro(bool Val) {
234 if (IsDeprecatedMacro == Val)
235 return;
236 IsDeprecatedMacro = Val;
237 if (Val)
238 NeedsHandleIdentifier = true;
239 else
240 RecomputeNeedsHandleIdentifier();
241 }
242
243 bool isRestrictExpansion() const { return IsRestrictExpansion; }
244
245 void setIsRestrictExpansion(bool Val) {
246 if (IsRestrictExpansion == Val)
247 return;
248 IsRestrictExpansion = Val;
249 if (Val)
250 NeedsHandleIdentifier = true;
251 else
252 RecomputeNeedsHandleIdentifier();
253 }
254
255 bool isFinal() const { return IsFinal; }
256
257 void setIsFinal(bool Val) { IsFinal = Val; }
258
259 /// If this is a source-language token (e.g. 'for'), this API
260 /// can be used to cause the lexer to map identifiers to source-language
261 /// tokens.
262 tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
263
264 /// True if revertTokenIDToIdentifier() was called.
265 bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; }
266
267 /// Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2
268 /// compatibility.
269 ///
270 /// TokenID is normally read-only but there are 2 instances where we revert it
271 /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens
272 /// using this method so we can inform serialization about it.
274 assert(TokenID != tok::identifier && "Already at tok::identifier");
275 TokenID = tok::identifier;
276 RevertedTokenID = true;
277 }
279 assert(TokenID == tok::identifier && "Should be at tok::identifier");
280 TokenID = TK;
281 RevertedTokenID = false;
282 }
283
284 /// Return the preprocessor keyword ID for this identifier.
285 ///
286 /// For example, "define" will return tok::pp_define.
287 tok::PPKeywordKind getPPKeywordID() const;
288
289 /// Return the Objective-C keyword ID for the this identifier.
290 ///
291 /// For example, 'class' will return tok::objc_class if ObjC is enabled.
293 if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
294 return tok::ObjCKeywordKind(ObjCOrBuiltinID);
295 else
296 return tok::objc_not_keyword;
297 }
298 void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; }
299
300 /// Return a value indicating whether this is a builtin function.
301 ///
302 /// 0 is not-built-in. 1+ are specific builtin functions.
303 unsigned getBuiltinID() const {
304 if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
305 return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
306 else
307 return 0;
308 }
309 void setBuiltinID(unsigned ID) {
310 ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
311 assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
312 && "ID too large for field!");
313 }
314
315 unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
316 void setObjCOrBuiltinID(unsigned ID) { ObjCOrBuiltinID = ID; }
317
318 /// get/setExtension - Initialize information about whether or not this
319 /// language token is an extension. This controls extension warnings, and is
320 /// only valid if a custom token ID is set.
321 bool isExtensionToken() const { return IsExtension; }
322 void setIsExtensionToken(bool Val) {
323 IsExtension = Val;
324 if (Val)
325 NeedsHandleIdentifier = true;
326 else
327 RecomputeNeedsHandleIdentifier();
328 }
329
330 /// is/setIsFutureCompatKeyword - Initialize information about whether or not
331 /// this language token is a keyword in a newer or proposed Standard. This
332 /// controls compatibility warnings, and is only true when not parsing the
333 /// corresponding Standard. Once a compatibility problem has been diagnosed
334 /// with this keyword, the flag will be cleared.
335 bool isFutureCompatKeyword() const { return IsFutureCompatKeyword; }
337 IsFutureCompatKeyword = Val;
338 if (Val)
339 NeedsHandleIdentifier = true;
340 else
341 RecomputeNeedsHandleIdentifier();
342 }
343
344 /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
345 /// Preprocessor will emit an error every time this token is used.
346 void setIsPoisoned(bool Value = true) {
347 IsPoisoned = Value;
348 if (Value)
349 NeedsHandleIdentifier = true;
350 else
351 RecomputeNeedsHandleIdentifier();
352 }
353
354 /// Return true if this token has been poisoned.
355 bool isPoisoned() const { return IsPoisoned; }
356
357 /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
358 /// this identifier is a C++ alternate representation of an operator.
359 void setIsCPlusPlusOperatorKeyword(bool Val = true) {
360 IsCPPOperatorKeyword = Val;
361 }
362 bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
363
364 /// Return true if this token is a keyword in the specified language.
365 bool isKeyword(const LangOptions &LangOpts) const;
366
367 /// Return true if this token is a C++ keyword in the specified
368 /// language.
369 bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
370
371 /// Get and set FETokenInfo. The language front-end is allowed to associate
372 /// arbitrary metadata with this token.
373 void *getFETokenInfo() const { return FETokenInfo; }
374 void setFETokenInfo(void *T) { FETokenInfo = T; }
375
376 /// Return true if the Preprocessor::HandleIdentifier must be called
377 /// on a token of this identifier.
378 ///
379 /// If this returns false, we know that HandleIdentifier will not affect
380 /// the token.
381 bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
382
383 /// Return true if the identifier in its current state was loaded
384 /// from an AST file.
385 bool isFromAST() const { return IsFromAST; }
386
387 void setIsFromAST() { IsFromAST = true; }
388
389 /// Determine whether this identifier has changed since it was loaded
390 /// from an AST file.
392 return ChangedAfterLoad;
393 }
394
395 /// Note that this identifier has changed since it was loaded from
396 /// an AST file.
398 ChangedAfterLoad = true;
399 }
400
401 /// Determine whether the frontend token information for this
402 /// identifier has changed since it was loaded from an AST file.
404 return FEChangedAfterLoad;
405 }
406
407 /// Note that the frontend token information for this identifier has
408 /// changed since it was loaded from an AST file.
410 FEChangedAfterLoad = true;
411 }
412
413 /// Determine whether the information for this identifier is out of
414 /// date with respect to the external source.
415 bool isOutOfDate() const { return OutOfDate; }
416
417 /// Set whether the information for this identifier is out of
418 /// date with respect to the external source.
419 void setOutOfDate(bool OOD) {
420 OutOfDate = OOD;
421 if (OOD)
422 NeedsHandleIdentifier = true;
423 else
424 RecomputeNeedsHandleIdentifier();
425 }
426
427 /// Determine whether this is the contextual keyword \c import.
428 bool isModulesImport() const { return IsModulesImport; }
429
430 /// Set whether this identifier is the contextual keyword \c import.
431 void setModulesImport(bool I) {
432 IsModulesImport = I;
433 if (I)
434 NeedsHandleIdentifier = true;
435 else
436 RecomputeNeedsHandleIdentifier();
437 }
438
439 /// Determine whether this is the mangled name of an OpenMP variant.
440 bool isMangledOpenMPVariantName() const { return IsMangledOpenMPVariantName; }
441
442 /// Set whether this is the mangled name of an OpenMP variant.
443 void setMangledOpenMPVariantName(bool I) { IsMangledOpenMPVariantName = I; }
444
445 /// Return true if this identifier is an editor placeholder.
446 ///
447 /// Editor placeholders are produced by the code-completion engine and are
448 /// represented as characters between '<#' and '#>' in the source code. An
449 /// example of auto-completed call with a placeholder parameter is shown
450 /// below:
451 /// \code
452 /// function(<#int x#>);
453 /// \endcode
454 bool isEditorPlaceholder() const {
455 return getName().startswith("<#") && getName().endswith("#>");
456 }
457
458 /// Determine whether \p this is a name reserved for the implementation (C99
459 /// 7.1.3, C++ [lib.global.names]).
460 ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const;
461
462 /// If the identifier is an "uglified" reserved name, return a cleaned form.
463 /// e.g. _Foo => Foo. Otherwise, just returns the name.
464 StringRef deuglifiedName() const;
465
466 /// Provide less than operator for lexicographical sorting.
467 bool operator<(const IdentifierInfo &RHS) const {
468 return getName() < RHS.getName();
469 }
470
471private:
472 /// The Preprocessor::HandleIdentifier does several special (but rare)
473 /// things to identifiers of various sorts. For example, it changes the
474 /// \c for keyword token from tok::identifier to tok::for.
475 ///
476 /// This method is very tied to the definition of HandleIdentifier. Any
477 /// change to it should be reflected here.
478 void RecomputeNeedsHandleIdentifier() {
479 NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() ||
480 isExtensionToken() || isFutureCompatKeyword() ||
481 isOutOfDate() || isModulesImport();
482 }
483};
484
485/// An RAII object for [un]poisoning an identifier within a scope.
486///
487/// \p II is allowed to be null, in which case objects of this type have
488/// no effect.
490 IdentifierInfo *const II;
491 const bool OldValue;
492
493public:
495 : II(II), OldValue(II ? II->isPoisoned() : false) {
496 if(II)
497 II->setIsPoisoned(NewValue);
498 }
499
501 if(II)
502 II->setIsPoisoned(OldValue);
503 }
504};
505
506/// An iterator that walks over all of the known identifiers
507/// in the lookup table.
508///
509/// Since this iterator uses an abstract interface via virtual
510/// functions, it uses an object-oriented interface rather than the
511/// more standard C++ STL iterator interface. In this OO-style
512/// iteration, the single function \c Next() provides dereference,
513/// advance, and end-of-sequence checking in a single
514/// operation. Subclasses of this iterator type will provide the
515/// actual functionality.
517protected:
519
520public:
523
525
526 /// Retrieve the next string in the identifier table and
527 /// advances the iterator for the following string.
528 ///
529 /// \returns The next string in the identifier table. If there is
530 /// no such string, returns an empty \c StringRef.
531 virtual StringRef Next() = 0;
532};
533
534/// Provides lookups to, and iteration over, IdentiferInfo objects.
536public:
538
539 /// Return the IdentifierInfo for the specified named identifier.
540 ///
541 /// Unlike the version in IdentifierTable, this returns a pointer instead
542 /// of a reference. If the pointer is null then the IdentifierInfo cannot
543 /// be found.
544 virtual IdentifierInfo* get(StringRef Name) = 0;
545
546 /// Retrieve an iterator into the set of all identifiers
547 /// known to this identifier lookup source.
548 ///
549 /// This routine provides access to all of the identifiers known to
550 /// the identifier lookup, allowing access to the contents of the
551 /// identifiers without introducing the overhead of constructing
552 /// IdentifierInfo objects for each.
553 ///
554 /// \returns A new iterator into the set of known identifiers. The
555 /// caller is responsible for deleting this iterator.
556 virtual IdentifierIterator *getIdentifiers();
557};
558
559/// Implements an efficient mapping from strings to IdentifierInfo nodes.
560///
561/// This has no other purpose, but this is an extremely performance-critical
562/// piece of the code, as each occurrence of every identifier goes through
563/// here when lexed.
565 // Shark shows that using MallocAllocator is *much* slower than using this
566 // BumpPtrAllocator!
567 using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>;
568 HashTableTy HashTable;
569
570 IdentifierInfoLookup* ExternalLookup;
571
572public:
573 /// Create the identifier table.
574 explicit IdentifierTable(IdentifierInfoLookup *ExternalLookup = nullptr);
575
576 /// Create the identifier table, populating it with info about the
577 /// language keywords for the language specified by \p LangOpts.
578 explicit IdentifierTable(const LangOptions &LangOpts,
579 IdentifierInfoLookup *ExternalLookup = nullptr);
580
581 /// Set the external identifier lookup mechanism.
583 ExternalLookup = IILookup;
584 }
585
586 /// Retrieve the external identifier lookup object, if any.
588 return ExternalLookup;
589 }
590
591 llvm::BumpPtrAllocator& getAllocator() {
592 return HashTable.getAllocator();
593 }
594
595 /// Return the identifier token info for the specified named
596 /// identifier.
597 IdentifierInfo &get(StringRef Name) {
598 auto &Entry = *HashTable.try_emplace(Name, nullptr).first;
599
600 IdentifierInfo *&II = Entry.second;
601 if (II) return *II;
602
603 // No entry; if we have an external lookup, look there first.
604 if (ExternalLookup) {
605 II = ExternalLookup->get(Name);
606 if (II)
607 return *II;
608 }
609
610 // Lookups failed, make a new IdentifierInfo.
611 void *Mem = getAllocator().Allocate<IdentifierInfo>();
612 II = new (Mem) IdentifierInfo();
613
614 // Make sure getName() knows how to find the IdentifierInfo
615 // contents.
616 II->Entry = &Entry;
617
618 return *II;
619 }
620
621 IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) {
622 IdentifierInfo &II = get(Name);
623 II.TokenID = TokenCode;
624 assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large");
625 return II;
626 }
627
628 /// Gets an IdentifierInfo for the given name without consulting
629 /// external sources.
630 ///
631 /// This is a version of get() meant for external sources that want to
632 /// introduce or modify an identifier. If they called get(), they would
633 /// likely end up in a recursion.
634 IdentifierInfo &getOwn(StringRef Name) {
635 auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
636
637 IdentifierInfo *&II = Entry.second;
638 if (II)
639 return *II;
640
641 // Lookups failed, make a new IdentifierInfo.
642 void *Mem = getAllocator().Allocate<IdentifierInfo>();
643 II = new (Mem) IdentifierInfo();
644
645 // Make sure getName() knows how to find the IdentifierInfo
646 // contents.
647 II->Entry = &Entry;
648
649 // If this is the 'import' contextual keyword, mark it as such.
650 if (Name.equals("import"))
651 II->setModulesImport(true);
652
653 return *II;
654 }
655
656 using iterator = HashTableTy::const_iterator;
657 using const_iterator = HashTableTy::const_iterator;
658
659 iterator begin() const { return HashTable.begin(); }
660 iterator end() const { return HashTable.end(); }
661 unsigned size() const { return HashTable.size(); }
662
663 iterator find(StringRef Name) const { return HashTable.find(Name); }
664
665 /// Print some statistics to stderr that indicate how well the
666 /// hashing is doing.
667 void PrintStats() const;
668
669 /// Populate the identifier table with info about the language keywords
670 /// for the language specified by \p LangOpts.
671 void AddKeywords(const LangOptions &LangOpts);
672
673 /// Returns the correct diagnostic to issue for a future-compat diagnostic
674 /// warning. Note, this function assumes the identifier passed has already
675 /// been determined to be a future compatible keyword.
676 diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
677 const LangOptions &LangOpts);
678};
679
680/// A family of Objective-C methods.
681///
682/// These families have no inherent meaning in the language, but are
683/// nonetheless central enough in the existing implementations to
684/// merit direct AST support. While, in theory, arbitrary methods can
685/// be considered to form families, we focus here on the methods
686/// involving allocation and retain-count management, as these are the
687/// most "core" and the most likely to be useful to diverse clients
688/// without extra information.
689///
690/// Both selectors and actual method declarations may be classified
691/// into families. Method families may impose additional restrictions
692/// beyond their selector name; for example, a method called '_init'
693/// that returns void is not considered to be in the 'init' family
694/// (but would be if it returned 'id'). It is also possible to
695/// explicitly change or remove a method's family. Therefore the
696/// method's family should be considered the single source of truth.
698 /// No particular method family.
700
701 // Selectors in these families may have arbitrary arity, may be
702 // written with arbitrary leading underscores, and may have
703 // additional CamelCase "words" in their first selector chunk
704 // following the family name.
710
711 // These families are singletons consisting only of the nullary
712 // selector with the given name.
721
722 // performSelector families
725
726/// Enough bits to store any enumerator in ObjCMethodFamily or
727/// InvalidObjCMethodFamily.
729
730/// An invalid value of ObjCMethodFamily.
732
733/// A family of Objective-C methods.
734///
735/// These are family of methods whose result type is initially 'id', but
736/// but are candidate for the result type to be changed to 'instancetype'.
745
751
752/// Smart pointer class that efficiently represents Objective-C method
753/// names.
754///
755/// This class will either point to an IdentifierInfo or a
756/// MultiKeywordSelector (which is private). This enables us to optimize
757/// selectors that take no arguments and selectors that take 1 argument, which
758/// accounts for 78% of all selectors in Cocoa.h.
759class Selector {
760 friend class Diagnostic;
761 friend class SelectorTable; // only the SelectorTable can create these
762 friend class DeclarationName; // and the AST's DeclarationName.
763
764 enum IdentifierInfoFlag {
765 // Empty selector = 0. Note that these enumeration values must
766 // correspond to the enumeration values of DeclarationName::StoredNameKind
767 ZeroArg = 0x01,
768 OneArg = 0x02,
769 MultiArg = 0x07,
770 ArgFlags = 0x07
771 };
772
773 /// A pointer to the MultiKeywordSelector or IdentifierInfo. We use the low
774 /// three bits of InfoPtr to store an IdentifierInfoFlag. Note that in any
775 /// case IdentifierInfo and MultiKeywordSelector are already aligned to
776 /// 8 bytes even on 32 bits archs because of DeclarationName.
777 uintptr_t InfoPtr = 0;
778
779 Selector(IdentifierInfo *II, unsigned nArgs) {
780 InfoPtr = reinterpret_cast<uintptr_t>(II);
781 assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
782 assert(nArgs < 2 && "nArgs not equal to 0/1");
783 InfoPtr |= nArgs+1;
784 }
785
786 Selector(MultiKeywordSelector *SI) {
787 InfoPtr = reinterpret_cast<uintptr_t>(SI);
788 assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
789 InfoPtr |= MultiArg;
790 }
791
792 IdentifierInfo *getAsIdentifierInfo() const {
793 if (getIdentifierInfoFlag() < MultiArg)
794 return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
795 return nullptr;
796 }
797
798 MultiKeywordSelector *getMultiKeywordSelector() const {
799 return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
800 }
801
802 unsigned getIdentifierInfoFlag() const {
803 return InfoPtr & ArgFlags;
804 }
805
806 static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
807
808 static ObjCStringFormatFamily getStringFormatFamilyImpl(Selector sel);
809
810public:
811 /// The default ctor should only be used when creating data structures that
812 /// will contain selectors.
813 Selector() = default;
814 explicit Selector(uintptr_t V) : InfoPtr(V) {}
815
816 /// operator==/!= - Indicate whether the specified selectors are identical.
817 bool operator==(Selector RHS) const {
818 return InfoPtr == RHS.InfoPtr;
819 }
820 bool operator!=(Selector RHS) const {
821 return InfoPtr != RHS.InfoPtr;
822 }
823
824 void *getAsOpaquePtr() const {
825 return reinterpret_cast<void*>(InfoPtr);
826 }
827
828 /// Determine whether this is the empty selector.
829 bool isNull() const { return InfoPtr == 0; }
830
831 // Predicates to identify the selector type.
832 bool isKeywordSelector() const {
833 return getIdentifierInfoFlag() != ZeroArg;
834 }
835
836 bool isUnarySelector() const {
837 return getIdentifierInfoFlag() == ZeroArg;
838 }
839
840 /// If this selector is the specific keyword selector described by Names.
841 bool isKeywordSelector(ArrayRef<StringRef> Names) const;
842
843 /// If this selector is the specific unary selector described by Name.
844 bool isUnarySelector(StringRef Name) const;
845
846 unsigned getNumArgs() const;
847
848 /// Retrieve the identifier at a given position in the selector.
849 ///
850 /// Note that the identifier pointer returned may be NULL. Clients that only
851 /// care about the text of the identifier string, and not the specific,
852 /// uniqued identifier pointer, should use \c getNameForSlot(), which returns
853 /// an empty string when the identifier pointer would be NULL.
854 ///
855 /// \param argIndex The index for which we want to retrieve the identifier.
856 /// This index shall be less than \c getNumArgs() unless this is a keyword
857 /// selector, in which case 0 is the only permissible value.
858 ///
859 /// \returns the uniqued identifier for this slot, or NULL if this slot has
860 /// no corresponding identifier.
861 IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
862
863 /// Retrieve the name at a given position in the selector.
864 ///
865 /// \param argIndex The index for which we want to retrieve the name.
866 /// This index shall be less than \c getNumArgs() unless this is a keyword
867 /// selector, in which case 0 is the only permissible value.
868 ///
869 /// \returns the name for this slot, which may be the empty string if no
870 /// name was supplied.
871 StringRef getNameForSlot(unsigned argIndex) const;
872
873 /// Derive the full selector name (e.g. "foo:bar:") and return
874 /// it as an std::string.
875 std::string getAsString() const;
876
877 /// Prints the full selector name (e.g. "foo:bar:").
878 void print(llvm::raw_ostream &OS) const;
879
880 void dump() const;
881
882 /// Derive the conventional family of this method.
884 return getMethodFamilyImpl(*this);
885 }
886
888 return getStringFormatFamilyImpl(*this);
889 }
890
892 return Selector(uintptr_t(-1));
893 }
894
896 return Selector(uintptr_t(-2));
897 }
898
899 static ObjCInstanceTypeFamily getInstTypeMethodFamily(Selector sel);
900};
901
902/// This table allows us to fully hide how we implement
903/// multi-keyword caching.
905 // Actually a SelectorTableImpl
906 void *Impl;
907
908public:
910 SelectorTable(const SelectorTable &) = delete;
913
914 /// Can create any sort of selector.
915 ///
916 /// \p NumArgs indicates whether this is a no argument selector "foo", a
917 /// single argument selector "foo:" or multi-argument "foo:bar:".
918 Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
919
921 return Selector(ID, 1);
922 }
923
925 return Selector(ID, 0);
926 }
927
928 /// Return the total amount of memory allocated for managing selectors.
929 size_t getTotalMemory() const;
930
931 /// Return the default setter name for the given identifier.
932 ///
933 /// This is "set" + \p Name where the initial character of \p Name
934 /// has been capitalized.
935 static SmallString<64> constructSetterName(StringRef Name);
936
937 /// Return the default setter selector for the given identifier.
938 ///
939 /// This is "set" + \p Name where the initial character of \p Name
940 /// has been capitalized.
941 static Selector constructSetterSelector(IdentifierTable &Idents,
942 SelectorTable &SelTable,
943 const IdentifierInfo *Name);
944
945 /// Return the property name for the given setter selector.
946 static std::string getPropertyNameFromSetterSelector(Selector Sel);
947};
948
949namespace detail {
950
951/// DeclarationNameExtra is used as a base of various uncommon special names.
952/// This class is needed since DeclarationName has not enough space to store
953/// the kind of every possible names. Therefore the kind of common names is
954/// stored directly in DeclarationName, and the kind of uncommon names is
955/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
956/// DeclarationName needs the lower 3 bits to store the kind of common names.
957/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
958/// here is very likely to require changes in DeclarationName(Table).
959class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
962
963protected:
964 /// The kind of "extra" information stored in the DeclarationName. See
965 /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
966 /// are used. Note that DeclarationName depends on the numerical values
967 /// of the enumerators in this enum. See DeclarationName::StoredNameKind
968 /// for more info.
973 ObjCMultiArgSelector
974 };
975
976 /// ExtraKindOrNumArgs has one of the following meaning:
977 /// * The kind of an uncommon C++ special name. This DeclarationNameExtra
978 /// is in this case in fact either a CXXDeductionGuideNameExtra or
979 /// a CXXLiteralOperatorIdName.
980 ///
981 /// * It may be also name common to C++ using-directives (CXXUsingDirective),
982 ///
983 /// * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
984 /// the number of arguments in the Objective-C selector, in which
985 /// case the DeclarationNameExtra is also a MultiKeywordSelector.
987
988 DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
989 DeclarationNameExtra(unsigned NumArgs)
990 : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
991
992 /// Return the corresponding ExtraKind.
994 return static_cast<ExtraKind>(ExtraKindOrNumArgs >
995 (unsigned)ObjCMultiArgSelector
996 ? (unsigned)ObjCMultiArgSelector
997 : ExtraKindOrNumArgs);
998 }
999
1000 /// Return the number of arguments in an ObjC selector. Only valid when this
1001 /// is indeed an ObjCMultiArgSelector.
1002 unsigned getNumArgs() const {
1003 assert(ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector &&
1004 "getNumArgs called but this is not an ObjC selector!");
1005 return ExtraKindOrNumArgs - (unsigned)ObjCMultiArgSelector;
1006 }
1007};
1008
1009} // namespace detail
1010
1011} // namespace clang
1012
1013namespace llvm {
1014
1015/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
1016/// DenseSets.
1017template <>
1018struct DenseMapInfo<clang::Selector> {
1021 }
1022
1025 }
1026
1027 static unsigned getHashValue(clang::Selector S);
1028
1030 return LHS == RHS;
1031 }
1032};
1033
1034template<>
1035struct PointerLikeTypeTraits<clang::Selector> {
1036 static const void *getAsVoidPointer(clang::Selector P) {
1037 return P.getAsOpaquePtr();
1038 }
1039
1041 return clang::Selector(reinterpret_cast<uintptr_t>(P));
1042 }
1043
1044 static constexpr int NumLowBitsAvailable = 0;
1045};
1046
1047// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
1048// are not guaranteed to be 8-byte aligned.
1049template<>
1050struct PointerLikeTypeTraits<clang::IdentifierInfo*> {
1052 return P;
1053 }
1054
1056 return static_cast<clang::IdentifierInfo*>(P);
1057 }
1058
1059 static constexpr int NumLowBitsAvailable = 1;
1060};
1061
1062template<>
1063struct PointerLikeTypeTraits<const clang::IdentifierInfo*> {
1064 static const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
1065 return P;
1066 }
1067
1068 static const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
1069 return static_cast<const clang::IdentifierInfo*>(P);
1070 }
1071
1072 static constexpr int NumLowBitsAvailable = 1;
1073};
1074
1075} // namespace llvm
1076
1077#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
#define V(N, I)
Definition: ASTContext.h:3230
StringRef P
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the Diagnostic IDs-related interfaces.
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &, QualType)
Definition: InterpFrame.cpp:89
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static std::string getName(const CallEvent &Call)
Defines the clang::TokenKind enum and support functions.
DeclarationNameTable is used to store and retrieve DeclarationName instances for the various kinds of...
The name of a declaration.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine) ...
Definition: Diagnostic.h:1566
Provides lookups to, and iteration over, IdentiferInfo objects.
virtual IdentifierInfo * get(StringRef Name)=0
Return the IdentifierInfo for the specified named identifier.
One of these records is kept for each identifier that is lexed.
bool isHandleIdentifierCase() const
Return true if the Preprocessor::HandleIdentifier must be called on a token of this identifier.
IdentifierInfo(const IdentifierInfo &)=delete
IdentifierInfo(IdentifierInfo &&)=delete
bool isModulesImport() const
Determine whether this is the contextual keyword import.
void revertIdentifierToTokenID(tok::TokenKind TK)
unsigned getLength() const
Efficiently return the length of this identifier info.
unsigned getBuiltinID() const
Return a value indicating whether this is a builtin function.
void setModulesImport(bool I)
Set whether this identifier is the contextual keyword import.
void setIsExtensionToken(bool Val)
void setIsRestrictExpansion(bool Val)
void setFETokenInfo(void *T)
bool hasChangedSinceDeserialization() const
Determine whether this identifier has changed since it was loaded from an AST file.
bool isCPlusPlusOperatorKeyword() const
IdentifierInfo & operator=(const IdentifierInfo &)=delete
void setIsDeprecatedMacro(bool Val)
bool hasFETokenInfoChangedSinceDeserialization() const
Determine whether the frontend token information for this identifier has changed since it was loaded ...
void setMangledOpenMPVariantName(bool I)
Set whether this is the mangled name of an OpenMP variant.
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.
void setIsPoisoned(bool Value=true)
setIsPoisoned - Mark this identifier as poisoned.
void setObjCKeywordID(tok::ObjCKeywordKind ID)
void setIsFinal(bool Val)
IdentifierInfo & operator=(IdentifierInfo &&)=delete
bool hasMacroDefinition() const
Return true if this identifier is #defined to some other value.
bool isFromAST() const
Return true if the identifier in its current state was loaded from an AST file.
bool isPoisoned() const
Return true if this token has been poisoned.
bool hasRevertedTokenIDToIdentifier() const
True if revertTokenIDToIdentifier() was called.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isMangledOpenMPVariantName() const
Determine whether this is the mangled name of an OpenMP variant.
void setOutOfDate(bool OOD)
Set whether the information for this identifier is out of date with respect to the external source.
void setHasMacroDefinition(bool Val)
bool isStr(llvm::StringRef Str) const
Return true if this is the identifier for the specified StringRef.
unsigned getObjCOrBuiltinID() const
tok::ObjCKeywordKind getObjCKeywordID() const
Return the Objective-C keyword ID for the this identifier.
void setObjCOrBuiltinID(unsigned ID)
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
bool isEditorPlaceholder() const
Return true if this identifier is an editor placeholder.
void setIsCPlusPlusOperatorKeyword(bool Val=true)
isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether this identifier is a C++ al...
void setBuiltinID(unsigned ID)
void setFETokenInfoChangedSinceDeserialization()
Note that the frontend token information for this identifier has changed since it was loaded from an ...
bool operator<(const IdentifierInfo &RHS) const
Provide less than operator for lexicographical sorting.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
bool isDeprecatedMacro() const
bool isOutOfDate() const
Determine whether the information for this identifier is out of date with respect to the external sou...
void setIsFutureCompatKeyword(bool Val)
void setChangedSinceDeserialization()
Note that this identifier has changed since it was loaded from an AST file.
void * getFETokenInfo() const
Get and set FETokenInfo.
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...
bool isExtensionToken() const
get/setExtension - Initialize information about whether or not this language token is an extension.
bool isRestrictExpansion() const
An iterator that walks over all of the known identifiers in the lookup table.
virtual StringRef Next()=0
Retrieve the next string in the identifier table and advances the iterator for the following string.
IdentifierIterator & operator=(const IdentifierIterator &)=delete
IdentifierIterator(const IdentifierIterator &)=delete
Implements an efficient mapping from strings to IdentifierInfo nodes.
unsigned size() const
IdentifierInfo & getOwn(StringRef Name)
Gets an IdentifierInfo for the given name without consulting external sources.
iterator find(StringRef Name) const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IdentifierInfo & get(StringRef Name, tok::TokenKind TokenCode)
iterator begin() const
IdentifierInfoLookup * getExternalIdentifierLookup() const
Retrieve the external identifier lookup object, if any.
HashTableTy::const_iterator iterator
iterator end() const
HashTableTy::const_iterator const_iterator
llvm::BumpPtrAllocator & getAllocator()
void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup)
Set the external identifier lookup mechanism.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
An RAII object for [un]poisoning an identifier within a scope.
PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue)
This table allows us to fully hide how we implement multi-keyword caching.
SelectorTable(const SelectorTable &)=delete
SelectorTable & operator=(const SelectorTable &)=delete
Selector getNullarySelector(IdentifierInfo *ID)
Selector getUnarySelector(IdentifierInfo *ID)
Smart pointer class that efficiently represents Objective-C method names.
Selector()=default
The default ctor should only be used when creating data structures that will contain selectors.
static Selector getEmptyMarker()
static Selector getTombstoneMarker()
void * getAsOpaquePtr() const
bool isKeywordSelector() const
ObjCMethodFamily getMethodFamily() const
Derive the conventional family of this method.
bool operator==(Selector RHS) const
operator==/!= - Indicate whether the specified selectors are identical.
bool isUnarySelector() const
bool operator!=(Selector RHS) const
bool isNull() const
Determine whether this is the empty selector.
Selector(uintptr_t V)
ObjCStringFormatFamily getStringFormatFamily() const
DeclarationNameExtra is used as a base of various uncommon special names.
ExtraKind
The kind of "extra" information stored in the DeclarationName.
ExtraKind getKind() const
Return the corresponding ExtraKind.
unsigned ExtraKindOrNumArgs
ExtraKindOrNumArgs has one of the following meaning:
unsigned getNumArgs() const
Return the number of arguments in an ObjC selector.
ObjCKeywordKind
Provides a namespace for Objective-C keywords which start with an '@'.
Definition: TokenKinds.h:41
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
PPKeywordKind
Provides a namespace for preprocessor keywords which start with a '#' at the beginning of the line.
Definition: TokenKinds.h:33
ObjCStringFormatFamily
static constexpr int ObjCOrBuiltinIDBits
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
@ ObjCMethodFamilyBitWidth
ObjCMethodFamily
A family of Objective-C methods.
@ OMF_initialize
@ OMF_autorelease
@ OMF_mutableCopy
@ OMF_performSelector
@ OMF_None
No particular method family.
@ OMF_retainCount
@ InvalidObjCMethodFamily
@ IdentifierInfoAlignment
ObjCInstanceTypeFamily
A family of Objective-C methods.
@ OIT_Dictionary
@ OIT_ReturnsSelf
bool isReservedAtGlobalScope(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved for use as a name at global scope.
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:55
std::pair< IdentifierInfo *, SourceLocation > IdentifierLocPair
A simple pair of identifier info and location.
ReservedIdentifierStatus
YAML serialization mapping.
Definition: Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
#define false
Definition: stdbool.h:22
static clang::Selector getEmptyKey()
static bool isEqual(clang::Selector LHS, clang::Selector RHS)
static clang::Selector getTombstoneKey()
static void * getAsVoidPointer(clang::IdentifierInfo *P)
static clang::IdentifierInfo * getFromVoidPointer(void *P)
static clang::Selector getFromVoidPointer(const void *P)
static const void * getAsVoidPointer(clang::Selector P)
static const void * getAsVoidPointer(const clang::IdentifierInfo *P)
static const clang::IdentifierInfo * getFromVoidPointer(const void *P)