Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 | |||
18 | #include "clang/Basic/DiagnosticIDs.h" |
||
19 | #include "clang/Basic/LLVM.h" |
||
20 | #include "clang/Basic/TokenKinds.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 | |||
35 | namespace clang { |
||
36 | |||
37 | class DeclarationName; |
||
38 | class DeclarationNameTable; |
||
39 | class IdentifierInfo; |
||
40 | class LangOptions; |
||
41 | class MultiKeywordSelector; |
||
42 | class SourceLocation; |
||
43 | |||
44 | enum class ReservedIdentifierStatus { |
||
45 | NotReserved = 0, |
||
46 | StartsWithUnderscoreAtGlobalScope, |
||
47 | StartsWithUnderscoreAndIsExternC, |
||
48 | StartsWithDoubleUnderscore, |
||
49 | StartsWithUnderscoreFollowedByCapitalLetter, |
||
50 | ContainsDoubleUnderscore, |
||
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. |
||
56 | inline bool isReservedAtGlobalScope(ReservedIdentifierStatus Status) { |
||
57 | return Status != ReservedIdentifierStatus::NotReserved; |
||
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. |
||
63 | inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) { |
||
64 | return Status != ReservedIdentifierStatus::NotReserved && |
||
65 | Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope && |
||
66 | Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC; |
||
67 | } |
||
68 | |||
69 | /// A simple pair of identifier info and location. |
||
70 | using 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. |
||
75 | enum { IdentifierInfoAlignment = 8 }; |
||
76 | |||
77 | static 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. |
||
85 | class 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 | |||
158 | IdentifierInfo() |
||
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 | |||
167 | public: |
||
168 | IdentifierInfo(const IdentifierInfo &) = delete; |
||
169 | IdentifierInfo &operator=(const IdentifierInfo &) = delete; |
||
170 | IdentifierInfo(IdentifierInfo &&) = delete; |
||
171 | IdentifierInfo &operator=(IdentifierInfo &&) = delete; |
||
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. |
||
273 | void revertTokenIDToIdentifier() { |
||
274 | assert(TokenID != tok::identifier && "Already at tok::identifier"); |
||
275 | TokenID = tok::identifier; |
||
276 | RevertedTokenID = true; |
||
277 | } |
||
278 | void revertIdentifierToTokenID(tok::TokenKind TK) { |
||
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. |
||
292 | tok::ObjCKeywordKind getObjCKeywordID() const { |
||
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; } |
||
336 | void setIsFutureCompatKeyword(bool Val) { |
||
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. |
||
391 | bool hasChangedSinceDeserialization() const { |
||
392 | return ChangedAfterLoad; |
||
393 | } |
||
394 | |||
395 | /// Note that this identifier has changed since it was loaded from |
||
396 | /// an AST file. |
||
397 | void setChangedSinceDeserialization() { |
||
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. |
||
403 | bool hasFETokenInfoChangedSinceDeserialization() const { |
||
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. |
||
409 | void setFETokenInfoChangedSinceDeserialization() { |
||
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 | |||
471 | private: |
||
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. |
||
489 | class PoisonIdentifierRAIIObject { |
||
490 | IdentifierInfo *const II; |
||
491 | const bool OldValue; |
||
492 | |||
493 | public: |
||
494 | PoisonIdentifierRAIIObject(IdentifierInfo *II, bool NewValue) |
||
495 | : II(II), OldValue(II ? II->isPoisoned() : false) { |
||
496 | if(II) |
||
497 | II->setIsPoisoned(NewValue); |
||
498 | } |
||
499 | |||
500 | ~PoisonIdentifierRAIIObject() { |
||
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. |
||
516 | class IdentifierIterator { |
||
517 | protected: |
||
518 | IdentifierIterator() = default; |
||
519 | |||
520 | public: |
||
521 | IdentifierIterator(const IdentifierIterator &) = delete; |
||
522 | IdentifierIterator &operator=(const IdentifierIterator &) = delete; |
||
523 | |||
524 | virtual ~IdentifierIterator(); |
||
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. |
||
535 | class IdentifierInfoLookup { |
||
536 | public: |
||
537 | virtual ~IdentifierInfoLookup(); |
||
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. |
||
564 | class IdentifierTable { |
||
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 | |||
572 | public: |
||
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. |
||
582 | void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) { |
||
583 | ExternalLookup = IILookup; |
||
584 | } |
||
585 | |||
586 | /// Retrieve the external identifier lookup object, if any. |
||
587 | IdentifierInfoLookup *getExternalIdentifierLookup() const { |
||
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. |
||
697 | enum ObjCMethodFamily { |
||
698 | /// No particular method family. |
||
699 | OMF_None, |
||
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. |
||
705 | OMF_alloc, |
||
706 | OMF_copy, |
||
707 | OMF_init, |
||
708 | OMF_mutableCopy, |
||
709 | OMF_new, |
||
710 | |||
711 | // These families are singletons consisting only of the nullary |
||
712 | // selector with the given name. |
||
713 | OMF_autorelease, |
||
714 | OMF_dealloc, |
||
715 | OMF_finalize, |
||
716 | OMF_release, |
||
717 | OMF_retain, |
||
718 | OMF_retainCount, |
||
719 | OMF_self, |
||
720 | OMF_initialize, |
||
721 | |||
722 | // performSelector families |
||
723 | OMF_performSelector |
||
724 | }; |
||
725 | |||
726 | /// Enough bits to store any enumerator in ObjCMethodFamily or |
||
727 | /// InvalidObjCMethodFamily. |
||
728 | enum { ObjCMethodFamilyBitWidth = 4 }; |
||
729 | |||
730 | /// An invalid value of ObjCMethodFamily. |
||
731 | enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; |
||
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'. |
||
737 | enum ObjCInstanceTypeFamily { |
||
738 | OIT_None, |
||
739 | OIT_Array, |
||
740 | OIT_Dictionary, |
||
741 | OIT_Singleton, |
||
742 | OIT_Init, |
||
743 | OIT_ReturnsSelf |
||
744 | }; |
||
745 | |||
746 | enum ObjCStringFormatFamily { |
||
747 | SFF_None, |
||
748 | SFF_NSString, |
||
749 | SFF_CFString |
||
750 | }; |
||
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. |
||
759 | class 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 | |||
810 | public: |
||
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. |
||
883 | ObjCMethodFamily getMethodFamily() const { |
||
884 | return getMethodFamilyImpl(*this); |
||
885 | } |
||
886 | |||
887 | ObjCStringFormatFamily getStringFormatFamily() const { |
||
888 | return getStringFormatFamilyImpl(*this); |
||
889 | } |
||
890 | |||
891 | static Selector getEmptyMarker() { |
||
892 | return Selector(uintptr_t(-1)); |
||
893 | } |
||
894 | |||
895 | static Selector getTombstoneMarker() { |
||
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. |
||
904 | class SelectorTable { |
||
905 | // Actually a SelectorTableImpl |
||
906 | void *Impl; |
||
907 | |||
908 | public: |
||
909 | SelectorTable(); |
||
910 | SelectorTable(const SelectorTable &) = delete; |
||
911 | SelectorTable &operator=(const SelectorTable &) = delete; |
||
912 | ~SelectorTable(); |
||
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 | |||
920 | Selector getUnarySelector(IdentifierInfo *ID) { |
||
921 | return Selector(ID, 1); |
||
922 | } |
||
923 | |||
924 | Selector getNullarySelector(IdentifierInfo *ID) { |
||
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 | |||
949 | namespace 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). |
||
959 | class alignas(IdentifierInfoAlignment) DeclarationNameExtra { |
||
960 | friend class clang::DeclarationName; |
||
961 | friend class clang::DeclarationNameTable; |
||
962 | |||
963 | protected: |
||
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. |
||
969 | enum ExtraKind { |
||
970 | CXXDeductionGuideName, |
||
971 | CXXLiteralOperatorName, |
||
972 | CXXUsingDirective, |
||
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. |
||
986 | unsigned ExtraKindOrNumArgs; |
||
987 | |||
988 | DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {} |
||
989 | DeclarationNameExtra(unsigned NumArgs) |
||
990 | : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {} |
||
991 | |||
992 | /// Return the corresponding ExtraKind. |
||
993 | ExtraKind getKind() const { |
||
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 | |||
1013 | namespace llvm { |
||
1014 | |||
1015 | /// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and |
||
1016 | /// DenseSets. |
||
1017 | template <> |
||
1018 | struct DenseMapInfo<clang::Selector> { |
||
1019 | static clang::Selector getEmptyKey() { |
||
1020 | return clang::Selector::getEmptyMarker(); |
||
1021 | } |
||
1022 | |||
1023 | static clang::Selector getTombstoneKey() { |
||
1024 | return clang::Selector::getTombstoneMarker(); |
||
1025 | } |
||
1026 | |||
1027 | static unsigned getHashValue(clang::Selector S); |
||
1028 | |||
1029 | static bool isEqual(clang::Selector LHS, clang::Selector RHS) { |
||
1030 | return LHS == RHS; |
||
1031 | } |
||
1032 | }; |
||
1033 | |||
1034 | template<> |
||
1035 | struct PointerLikeTypeTraits<clang::Selector> { |
||
1036 | static const void *getAsVoidPointer(clang::Selector P) { |
||
1037 | return P.getAsOpaquePtr(); |
||
1038 | } |
||
1039 | |||
1040 | static clang::Selector getFromVoidPointer(const void *P) { |
||
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. |
||
1049 | template<> |
||
1050 | struct PointerLikeTypeTraits<clang::IdentifierInfo*> { |
||
1051 | static void *getAsVoidPointer(clang::IdentifierInfo* P) { |
||
1052 | return P; |
||
1053 | } |
||
1054 | |||
1055 | static clang::IdentifierInfo *getFromVoidPointer(void *P) { |
||
1056 | return static_cast<clang::IdentifierInfo*>(P); |
||
1057 | } |
||
1058 | |||
1059 | static constexpr int NumLowBitsAvailable = 1; |
||
1060 | }; |
||
1061 | |||
1062 | template<> |
||
1063 | struct 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 |