Coverage Report

Created: 2021-08-24 07:12

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