xref: /aosp_15_r20/external/clang/lib/Basic/IdentifierTable.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the IdentifierInfo, IdentifierVisitor, and
11*67e74705SXin Li // IdentifierTable interfaces.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "clang/Basic/CharInfo.h"
16*67e74705SXin Li #include "clang/Basic/IdentifierTable.h"
17*67e74705SXin Li #include "clang/Basic/LangOptions.h"
18*67e74705SXin Li #include "clang/Basic/OperatorKinds.h"
19*67e74705SXin Li #include "clang/Basic/Specifiers.h"
20*67e74705SXin Li #include "llvm/ADT/DenseMap.h"
21*67e74705SXin Li #include "llvm/ADT/FoldingSet.h"
22*67e74705SXin Li #include "llvm/ADT/SmallString.h"
23*67e74705SXin Li #include "llvm/Support/ErrorHandling.h"
24*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
25*67e74705SXin Li #include <cstdio>
26*67e74705SXin Li 
27*67e74705SXin Li using namespace clang;
28*67e74705SXin Li 
29*67e74705SXin Li //===----------------------------------------------------------------------===//
30*67e74705SXin Li // IdentifierInfo Implementation
31*67e74705SXin Li //===----------------------------------------------------------------------===//
32*67e74705SXin Li 
IdentifierInfo()33*67e74705SXin Li IdentifierInfo::IdentifierInfo() {
34*67e74705SXin Li   TokenID = tok::identifier;
35*67e74705SXin Li   ObjCOrBuiltinID = 0;
36*67e74705SXin Li   HasMacro = false;
37*67e74705SXin Li   HadMacro = false;
38*67e74705SXin Li   IsExtension = false;
39*67e74705SXin Li   IsFutureCompatKeyword = false;
40*67e74705SXin Li   IsPoisoned = false;
41*67e74705SXin Li   IsCPPOperatorKeyword = false;
42*67e74705SXin Li   NeedsHandleIdentifier = false;
43*67e74705SXin Li   IsFromAST = false;
44*67e74705SXin Li   ChangedAfterLoad = false;
45*67e74705SXin Li   FEChangedAfterLoad = false;
46*67e74705SXin Li   RevertedTokenID = false;
47*67e74705SXin Li   OutOfDate = false;
48*67e74705SXin Li   IsModulesImport = false;
49*67e74705SXin Li   FETokenInfo = nullptr;
50*67e74705SXin Li   Entry = nullptr;
51*67e74705SXin Li }
52*67e74705SXin Li 
53*67e74705SXin Li //===----------------------------------------------------------------------===//
54*67e74705SXin Li // IdentifierTable Implementation
55*67e74705SXin Li //===----------------------------------------------------------------------===//
56*67e74705SXin Li 
~IdentifierIterator()57*67e74705SXin Li IdentifierIterator::~IdentifierIterator() { }
58*67e74705SXin Li 
~IdentifierInfoLookup()59*67e74705SXin Li IdentifierInfoLookup::~IdentifierInfoLookup() {}
60*67e74705SXin Li 
61*67e74705SXin Li namespace {
62*67e74705SXin Li   /// \brief A simple identifier lookup iterator that represents an
63*67e74705SXin Li   /// empty sequence of identifiers.
64*67e74705SXin Li   class EmptyLookupIterator : public IdentifierIterator
65*67e74705SXin Li   {
66*67e74705SXin Li   public:
Next()67*67e74705SXin Li     StringRef Next() override { return StringRef(); }
68*67e74705SXin Li   };
69*67e74705SXin Li }
70*67e74705SXin Li 
getIdentifiers()71*67e74705SXin Li IdentifierIterator *IdentifierInfoLookup::getIdentifiers() {
72*67e74705SXin Li   return new EmptyLookupIterator();
73*67e74705SXin Li }
74*67e74705SXin Li 
IdentifierTable(const LangOptions & LangOpts,IdentifierInfoLookup * externalLookup)75*67e74705SXin Li IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
76*67e74705SXin Li                                  IdentifierInfoLookup* externalLookup)
77*67e74705SXin Li   : HashTable(8192), // Start with space for 8K identifiers.
78*67e74705SXin Li     ExternalLookup(externalLookup) {
79*67e74705SXin Li 
80*67e74705SXin Li   // Populate the identifier table with info about keywords for the current
81*67e74705SXin Li   // language.
82*67e74705SXin Li   AddKeywords(LangOpts);
83*67e74705SXin Li 
84*67e74705SXin Li 
85*67e74705SXin Li   // Add the '_experimental_modules_import' contextual keyword.
86*67e74705SXin Li   get("import").setModulesImport(true);
87*67e74705SXin Li }
88*67e74705SXin Li 
89*67e74705SXin Li //===----------------------------------------------------------------------===//
90*67e74705SXin Li // Language Keyword Implementation
91*67e74705SXin Li //===----------------------------------------------------------------------===//
92*67e74705SXin Li 
93*67e74705SXin Li // Constants for TokenKinds.def
94*67e74705SXin Li namespace {
95*67e74705SXin Li   enum {
96*67e74705SXin Li     KEYC99 = 0x1,
97*67e74705SXin Li     KEYCXX = 0x2,
98*67e74705SXin Li     KEYCXX11 = 0x4,
99*67e74705SXin Li     KEYGNU = 0x8,
100*67e74705SXin Li     KEYMS = 0x10,
101*67e74705SXin Li     BOOLSUPPORT = 0x20,
102*67e74705SXin Li     KEYALTIVEC = 0x40,
103*67e74705SXin Li     KEYNOCXX = 0x80,
104*67e74705SXin Li     KEYBORLAND = 0x100,
105*67e74705SXin Li     KEYOPENCL = 0x200,
106*67e74705SXin Li     KEYC11 = 0x400,
107*67e74705SXin Li     KEYARC = 0x800,
108*67e74705SXin Li     KEYNOMS18 = 0x01000,
109*67e74705SXin Li     KEYNOOPENCL = 0x02000,
110*67e74705SXin Li     WCHARSUPPORT = 0x04000,
111*67e74705SXin Li     HALFSUPPORT = 0x08000,
112*67e74705SXin Li     KEYCONCEPTS = 0x10000,
113*67e74705SXin Li     KEYOBJC2    = 0x20000,
114*67e74705SXin Li     KEYZVECTOR  = 0x40000,
115*67e74705SXin Li     KEYCOROUTINES = 0x80000,
116*67e74705SXin Li     KEYALL = (0xfffff & ~KEYNOMS18 &
117*67e74705SXin Li               ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
118*67e74705SXin Li   };
119*67e74705SXin Li 
120*67e74705SXin Li   /// \brief How a keyword is treated in the selected standard.
121*67e74705SXin Li   enum KeywordStatus {
122*67e74705SXin Li     KS_Disabled,    // Disabled
123*67e74705SXin Li     KS_Extension,   // Is an extension
124*67e74705SXin Li     KS_Enabled,     // Enabled
125*67e74705SXin Li     KS_Future       // Is a keyword in future standard
126*67e74705SXin Li   };
127*67e74705SXin Li }
128*67e74705SXin Li 
129*67e74705SXin Li /// \brief Translates flags as specified in TokenKinds.def into keyword status
130*67e74705SXin Li /// in the given language standard.
getKeywordStatus(const LangOptions & LangOpts,unsigned Flags)131*67e74705SXin Li static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
132*67e74705SXin Li                                       unsigned Flags) {
133*67e74705SXin Li   if (Flags == KEYALL) return KS_Enabled;
134*67e74705SXin Li   if (LangOpts.CPlusPlus && (Flags & KEYCXX)) return KS_Enabled;
135*67e74705SXin Li   if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) return KS_Enabled;
136*67e74705SXin Li   if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled;
137*67e74705SXin Li   if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension;
138*67e74705SXin Li   if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension;
139*67e74705SXin Li   if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension;
140*67e74705SXin Li   if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled;
141*67e74705SXin Li   if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled;
142*67e74705SXin Li   if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled;
143*67e74705SXin Li   if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled;
144*67e74705SXin Li   if (LangOpts.OpenCL && (Flags & KEYOPENCL)) return KS_Enabled;
145*67e74705SXin Li   if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled;
146*67e74705SXin Li   if (LangOpts.C11 && (Flags & KEYC11)) return KS_Enabled;
147*67e74705SXin Li   // We treat bridge casts as objective-C keywords so we can warn on them
148*67e74705SXin Li   // in non-arc mode.
149*67e74705SXin Li   if (LangOpts.ObjC2 && (Flags & KEYARC)) return KS_Enabled;
150*67e74705SXin Li   if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled;
151*67e74705SXin Li   if (LangOpts.ObjC2 && (Flags & KEYOBJC2)) return KS_Enabled;
152*67e74705SXin Li   if (LangOpts.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled;
153*67e74705SXin Li   if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) return KS_Future;
154*67e74705SXin Li   return KS_Disabled;
155*67e74705SXin Li }
156*67e74705SXin Li 
157*67e74705SXin Li /// AddKeyword - This method is used to associate a token ID with specific
158*67e74705SXin Li /// identifiers because they are language keywords.  This causes the lexer to
159*67e74705SXin Li /// automatically map matching identifiers to specialized token codes.
AddKeyword(StringRef Keyword,tok::TokenKind TokenCode,unsigned Flags,const LangOptions & LangOpts,IdentifierTable & Table)160*67e74705SXin Li static void AddKeyword(StringRef Keyword,
161*67e74705SXin Li                        tok::TokenKind TokenCode, unsigned Flags,
162*67e74705SXin Li                        const LangOptions &LangOpts, IdentifierTable &Table) {
163*67e74705SXin Li   KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags);
164*67e74705SXin Li 
165*67e74705SXin Li   // Don't add this keyword under MSVCCompat.
166*67e74705SXin Li   if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
167*67e74705SXin Li       !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
168*67e74705SXin Li     return;
169*67e74705SXin Li 
170*67e74705SXin Li   // Don't add this keyword under OpenCL.
171*67e74705SXin Li   if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
172*67e74705SXin Li     return;
173*67e74705SXin Li 
174*67e74705SXin Li   // Don't add this keyword if disabled in this language.
175*67e74705SXin Li   if (AddResult == KS_Disabled) return;
176*67e74705SXin Li 
177*67e74705SXin Li   IdentifierInfo &Info =
178*67e74705SXin Li       Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
179*67e74705SXin Li   Info.setIsExtensionToken(AddResult == KS_Extension);
180*67e74705SXin Li   Info.setIsFutureCompatKeyword(AddResult == KS_Future);
181*67e74705SXin Li }
182*67e74705SXin Li 
183*67e74705SXin Li /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
184*67e74705SXin Li /// representations.
AddCXXOperatorKeyword(StringRef Keyword,tok::TokenKind TokenCode,IdentifierTable & Table)185*67e74705SXin Li static void AddCXXOperatorKeyword(StringRef Keyword,
186*67e74705SXin Li                                   tok::TokenKind TokenCode,
187*67e74705SXin Li                                   IdentifierTable &Table) {
188*67e74705SXin Li   IdentifierInfo &Info = Table.get(Keyword, TokenCode);
189*67e74705SXin Li   Info.setIsCPlusPlusOperatorKeyword();
190*67e74705SXin Li }
191*67e74705SXin Li 
192*67e74705SXin Li /// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
193*67e74705SXin Li /// or "property".
AddObjCKeyword(StringRef Name,tok::ObjCKeywordKind ObjCID,IdentifierTable & Table)194*67e74705SXin Li static void AddObjCKeyword(StringRef Name,
195*67e74705SXin Li                            tok::ObjCKeywordKind ObjCID,
196*67e74705SXin Li                            IdentifierTable &Table) {
197*67e74705SXin Li   Table.get(Name).setObjCKeywordID(ObjCID);
198*67e74705SXin Li }
199*67e74705SXin Li 
200*67e74705SXin Li /// AddKeywords - Add all keywords to the symbol table.
201*67e74705SXin Li ///
AddKeywords(const LangOptions & LangOpts)202*67e74705SXin Li void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
203*67e74705SXin Li   // Add keywords and tokens for the current language.
204*67e74705SXin Li #define KEYWORD(NAME, FLAGS) \
205*67e74705SXin Li   AddKeyword(StringRef(#NAME), tok::kw_ ## NAME,  \
206*67e74705SXin Li              FLAGS, LangOpts, *this);
207*67e74705SXin Li #define ALIAS(NAME, TOK, FLAGS) \
208*67e74705SXin Li   AddKeyword(StringRef(NAME), tok::kw_ ## TOK,  \
209*67e74705SXin Li              FLAGS, LangOpts, *this);
210*67e74705SXin Li #define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
211*67e74705SXin Li   if (LangOpts.CXXOperatorNames)          \
212*67e74705SXin Li     AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
213*67e74705SXin Li #define OBJC1_AT_KEYWORD(NAME) \
214*67e74705SXin Li   if (LangOpts.ObjC1)          \
215*67e74705SXin Li     AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
216*67e74705SXin Li #define OBJC2_AT_KEYWORD(NAME) \
217*67e74705SXin Li   if (LangOpts.ObjC2)          \
218*67e74705SXin Li     AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
219*67e74705SXin Li #define TESTING_KEYWORD(NAME, FLAGS)
220*67e74705SXin Li #include "clang/Basic/TokenKinds.def"
221*67e74705SXin Li 
222*67e74705SXin Li   if (LangOpts.ParseUnknownAnytype)
223*67e74705SXin Li     AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
224*67e74705SXin Li                LangOpts, *this);
225*67e74705SXin Li 
226*67e74705SXin Li   if (LangOpts.DeclSpecKeyword)
227*67e74705SXin Li     AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);
228*67e74705SXin Li }
229*67e74705SXin Li 
230*67e74705SXin Li /// \brief Checks if the specified token kind represents a keyword in the
231*67e74705SXin Li /// specified language.
232*67e74705SXin Li /// \returns Status of the keyword in the language.
getTokenKwStatus(const LangOptions & LangOpts,tok::TokenKind K)233*67e74705SXin Li static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts,
234*67e74705SXin Li                                       tok::TokenKind K) {
235*67e74705SXin Li   switch (K) {
236*67e74705SXin Li #define KEYWORD(NAME, FLAGS) \
237*67e74705SXin Li   case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
238*67e74705SXin Li #include "clang/Basic/TokenKinds.def"
239*67e74705SXin Li   default: return KS_Disabled;
240*67e74705SXin Li   }
241*67e74705SXin Li }
242*67e74705SXin Li 
243*67e74705SXin Li /// \brief Returns true if the identifier represents a keyword in the
244*67e74705SXin Li /// specified language.
isKeyword(const LangOptions & LangOpts)245*67e74705SXin Li bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) {
246*67e74705SXin Li   switch (getTokenKwStatus(LangOpts, getTokenID())) {
247*67e74705SXin Li   case KS_Enabled:
248*67e74705SXin Li   case KS_Extension:
249*67e74705SXin Li     return true;
250*67e74705SXin Li   default:
251*67e74705SXin Li     return false;
252*67e74705SXin Li   }
253*67e74705SXin Li }
254*67e74705SXin Li 
getPPKeywordID() const255*67e74705SXin Li tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
256*67e74705SXin Li   // We use a perfect hash function here involving the length of the keyword,
257*67e74705SXin Li   // the first and third character.  For preprocessor ID's there are no
258*67e74705SXin Li   // collisions (if there were, the switch below would complain about duplicate
259*67e74705SXin Li   // case values).  Note that this depends on 'if' being null terminated.
260*67e74705SXin Li 
261*67e74705SXin Li #define HASH(LEN, FIRST, THIRD) \
262*67e74705SXin Li   (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31)
263*67e74705SXin Li #define CASE(LEN, FIRST, THIRD, NAME) \
264*67e74705SXin Li   case HASH(LEN, FIRST, THIRD): \
265*67e74705SXin Li     return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME
266*67e74705SXin Li 
267*67e74705SXin Li   unsigned Len = getLength();
268*67e74705SXin Li   if (Len < 2) return tok::pp_not_keyword;
269*67e74705SXin Li   const char *Name = getNameStart();
270*67e74705SXin Li   switch (HASH(Len, Name[0], Name[2])) {
271*67e74705SXin Li   default: return tok::pp_not_keyword;
272*67e74705SXin Li   CASE( 2, 'i', '\0', if);
273*67e74705SXin Li   CASE( 4, 'e', 'i', elif);
274*67e74705SXin Li   CASE( 4, 'e', 's', else);
275*67e74705SXin Li   CASE( 4, 'l', 'n', line);
276*67e74705SXin Li   CASE( 4, 's', 'c', sccs);
277*67e74705SXin Li   CASE( 5, 'e', 'd', endif);
278*67e74705SXin Li   CASE( 5, 'e', 'r', error);
279*67e74705SXin Li   CASE( 5, 'i', 'e', ident);
280*67e74705SXin Li   CASE( 5, 'i', 'd', ifdef);
281*67e74705SXin Li   CASE( 5, 'u', 'd', undef);
282*67e74705SXin Li 
283*67e74705SXin Li   CASE( 6, 'a', 's', assert);
284*67e74705SXin Li   CASE( 6, 'd', 'f', define);
285*67e74705SXin Li   CASE( 6, 'i', 'n', ifndef);
286*67e74705SXin Li   CASE( 6, 'i', 'p', import);
287*67e74705SXin Li   CASE( 6, 'p', 'a', pragma);
288*67e74705SXin Li 
289*67e74705SXin Li   CASE( 7, 'd', 'f', defined);
290*67e74705SXin Li   CASE( 7, 'i', 'c', include);
291*67e74705SXin Li   CASE( 7, 'w', 'r', warning);
292*67e74705SXin Li 
293*67e74705SXin Li   CASE( 8, 'u', 'a', unassert);
294*67e74705SXin Li   CASE(12, 'i', 'c', include_next);
295*67e74705SXin Li 
296*67e74705SXin Li   CASE(14, '_', 'p', __public_macro);
297*67e74705SXin Li 
298*67e74705SXin Li   CASE(15, '_', 'p', __private_macro);
299*67e74705SXin Li 
300*67e74705SXin Li   CASE(16, '_', 'i', __include_macros);
301*67e74705SXin Li #undef CASE
302*67e74705SXin Li #undef HASH
303*67e74705SXin Li   }
304*67e74705SXin Li }
305*67e74705SXin Li 
306*67e74705SXin Li //===----------------------------------------------------------------------===//
307*67e74705SXin Li // Stats Implementation
308*67e74705SXin Li //===----------------------------------------------------------------------===//
309*67e74705SXin Li 
310*67e74705SXin Li /// PrintStats - Print statistics about how well the identifier table is doing
311*67e74705SXin Li /// at hashing identifiers.
PrintStats() const312*67e74705SXin Li void IdentifierTable::PrintStats() const {
313*67e74705SXin Li   unsigned NumBuckets = HashTable.getNumBuckets();
314*67e74705SXin Li   unsigned NumIdentifiers = HashTable.getNumItems();
315*67e74705SXin Li   unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
316*67e74705SXin Li   unsigned AverageIdentifierSize = 0;
317*67e74705SXin Li   unsigned MaxIdentifierLength = 0;
318*67e74705SXin Li 
319*67e74705SXin Li   // TODO: Figure out maximum times an identifier had to probe for -stats.
320*67e74705SXin Li   for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
321*67e74705SXin Li        I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
322*67e74705SXin Li     unsigned IdLen = I->getKeyLength();
323*67e74705SXin Li     AverageIdentifierSize += IdLen;
324*67e74705SXin Li     if (MaxIdentifierLength < IdLen)
325*67e74705SXin Li       MaxIdentifierLength = IdLen;
326*67e74705SXin Li   }
327*67e74705SXin Li 
328*67e74705SXin Li   fprintf(stderr, "\n*** Identifier Table Stats:\n");
329*67e74705SXin Li   fprintf(stderr, "# Identifiers:   %d\n", NumIdentifiers);
330*67e74705SXin Li   fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
331*67e74705SXin Li   fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
332*67e74705SXin Li           NumIdentifiers/(double)NumBuckets);
333*67e74705SXin Li   fprintf(stderr, "Ave identifier length: %f\n",
334*67e74705SXin Li           (AverageIdentifierSize/(double)NumIdentifiers));
335*67e74705SXin Li   fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
336*67e74705SXin Li 
337*67e74705SXin Li   // Compute statistics about the memory allocated for identifiers.
338*67e74705SXin Li   HashTable.getAllocator().PrintStats();
339*67e74705SXin Li }
340*67e74705SXin Li 
341*67e74705SXin Li //===----------------------------------------------------------------------===//
342*67e74705SXin Li // SelectorTable Implementation
343*67e74705SXin Li //===----------------------------------------------------------------------===//
344*67e74705SXin Li 
getHashValue(clang::Selector S)345*67e74705SXin Li unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
346*67e74705SXin Li   return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
347*67e74705SXin Li }
348*67e74705SXin Li 
349*67e74705SXin Li namespace clang {
350*67e74705SXin Li /// MultiKeywordSelector - One of these variable length records is kept for each
351*67e74705SXin Li /// selector containing more than one keyword. We use a folding set
352*67e74705SXin Li /// to unique aggregate names (keyword selectors in ObjC parlance). Access to
353*67e74705SXin Li /// this class is provided strictly through Selector.
354*67e74705SXin Li class MultiKeywordSelector
355*67e74705SXin Li   : public DeclarationNameExtra, public llvm::FoldingSetNode {
MultiKeywordSelector(unsigned nKeys)356*67e74705SXin Li   MultiKeywordSelector(unsigned nKeys) {
357*67e74705SXin Li     ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
358*67e74705SXin Li   }
359*67e74705SXin Li public:
360*67e74705SXin Li   // Constructor for keyword selectors.
MultiKeywordSelector(unsigned nKeys,IdentifierInfo ** IIV)361*67e74705SXin Li   MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
362*67e74705SXin Li     assert((nKeys > 1) && "not a multi-keyword selector");
363*67e74705SXin Li     ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
364*67e74705SXin Li 
365*67e74705SXin Li     // Fill in the trailing keyword array.
366*67e74705SXin Li     IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
367*67e74705SXin Li     for (unsigned i = 0; i != nKeys; ++i)
368*67e74705SXin Li       KeyInfo[i] = IIV[i];
369*67e74705SXin Li   }
370*67e74705SXin Li 
371*67e74705SXin Li   // getName - Derive the full selector name and return it.
372*67e74705SXin Li   std::string getName() const;
373*67e74705SXin Li 
getNumArgs() const374*67e74705SXin Li   unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
375*67e74705SXin Li 
376*67e74705SXin Li   typedef IdentifierInfo *const *keyword_iterator;
keyword_begin() const377*67e74705SXin Li   keyword_iterator keyword_begin() const {
378*67e74705SXin Li     return reinterpret_cast<keyword_iterator>(this+1);
379*67e74705SXin Li   }
keyword_end() const380*67e74705SXin Li   keyword_iterator keyword_end() const {
381*67e74705SXin Li     return keyword_begin()+getNumArgs();
382*67e74705SXin Li   }
getIdentifierInfoForSlot(unsigned i) const383*67e74705SXin Li   IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
384*67e74705SXin Li     assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
385*67e74705SXin Li     return keyword_begin()[i];
386*67e74705SXin Li   }
Profile(llvm::FoldingSetNodeID & ID,keyword_iterator ArgTys,unsigned NumArgs)387*67e74705SXin Li   static void Profile(llvm::FoldingSetNodeID &ID,
388*67e74705SXin Li                       keyword_iterator ArgTys, unsigned NumArgs) {
389*67e74705SXin Li     ID.AddInteger(NumArgs);
390*67e74705SXin Li     for (unsigned i = 0; i != NumArgs; ++i)
391*67e74705SXin Li       ID.AddPointer(ArgTys[i]);
392*67e74705SXin Li   }
Profile(llvm::FoldingSetNodeID & ID)393*67e74705SXin Li   void Profile(llvm::FoldingSetNodeID &ID) {
394*67e74705SXin Li     Profile(ID, keyword_begin(), getNumArgs());
395*67e74705SXin Li   }
396*67e74705SXin Li };
397*67e74705SXin Li } // end namespace clang.
398*67e74705SXin Li 
getNumArgs() const399*67e74705SXin Li unsigned Selector::getNumArgs() const {
400*67e74705SXin Li   unsigned IIF = getIdentifierInfoFlag();
401*67e74705SXin Li   if (IIF <= ZeroArg)
402*67e74705SXin Li     return 0;
403*67e74705SXin Li   if (IIF == OneArg)
404*67e74705SXin Li     return 1;
405*67e74705SXin Li   // We point to a MultiKeywordSelector.
406*67e74705SXin Li   MultiKeywordSelector *SI = getMultiKeywordSelector();
407*67e74705SXin Li   return SI->getNumArgs();
408*67e74705SXin Li }
409*67e74705SXin Li 
getIdentifierInfoForSlot(unsigned argIndex) const410*67e74705SXin Li IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
411*67e74705SXin Li   if (getIdentifierInfoFlag() < MultiArg) {
412*67e74705SXin Li     assert(argIndex == 0 && "illegal keyword index");
413*67e74705SXin Li     return getAsIdentifierInfo();
414*67e74705SXin Li   }
415*67e74705SXin Li   // We point to a MultiKeywordSelector.
416*67e74705SXin Li   MultiKeywordSelector *SI = getMultiKeywordSelector();
417*67e74705SXin Li   return SI->getIdentifierInfoForSlot(argIndex);
418*67e74705SXin Li }
419*67e74705SXin Li 
getNameForSlot(unsigned int argIndex) const420*67e74705SXin Li StringRef Selector::getNameForSlot(unsigned int argIndex) const {
421*67e74705SXin Li   IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
422*67e74705SXin Li   return II? II->getName() : StringRef();
423*67e74705SXin Li }
424*67e74705SXin Li 
getName() const425*67e74705SXin Li std::string MultiKeywordSelector::getName() const {
426*67e74705SXin Li   SmallString<256> Str;
427*67e74705SXin Li   llvm::raw_svector_ostream OS(Str);
428*67e74705SXin Li   for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
429*67e74705SXin Li     if (*I)
430*67e74705SXin Li       OS << (*I)->getName();
431*67e74705SXin Li     OS << ':';
432*67e74705SXin Li   }
433*67e74705SXin Li 
434*67e74705SXin Li   return OS.str();
435*67e74705SXin Li }
436*67e74705SXin Li 
getAsString() const437*67e74705SXin Li std::string Selector::getAsString() const {
438*67e74705SXin Li   if (InfoPtr == 0)
439*67e74705SXin Li     return "<null selector>";
440*67e74705SXin Li 
441*67e74705SXin Li   if (getIdentifierInfoFlag() < MultiArg) {
442*67e74705SXin Li     IdentifierInfo *II = getAsIdentifierInfo();
443*67e74705SXin Li 
444*67e74705SXin Li     // If the number of arguments is 0 then II is guaranteed to not be null.
445*67e74705SXin Li     if (getNumArgs() == 0)
446*67e74705SXin Li       return II->getName();
447*67e74705SXin Li 
448*67e74705SXin Li     if (!II)
449*67e74705SXin Li       return ":";
450*67e74705SXin Li 
451*67e74705SXin Li     return II->getName().str() + ":";
452*67e74705SXin Li   }
453*67e74705SXin Li 
454*67e74705SXin Li   // We have a multiple keyword selector.
455*67e74705SXin Li   return getMultiKeywordSelector()->getName();
456*67e74705SXin Li }
457*67e74705SXin Li 
print(llvm::raw_ostream & OS) const458*67e74705SXin Li void Selector::print(llvm::raw_ostream &OS) const {
459*67e74705SXin Li   OS << getAsString();
460*67e74705SXin Li }
461*67e74705SXin Li 
462*67e74705SXin Li /// Interpreting the given string using the normal CamelCase
463*67e74705SXin Li /// conventions, determine whether the given string starts with the
464*67e74705SXin Li /// given "word", which is assumed to end in a lowercase letter.
startsWithWord(StringRef name,StringRef word)465*67e74705SXin Li static bool startsWithWord(StringRef name, StringRef word) {
466*67e74705SXin Li   if (name.size() < word.size()) return false;
467*67e74705SXin Li   return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
468*67e74705SXin Li           name.startswith(word));
469*67e74705SXin Li }
470*67e74705SXin Li 
getMethodFamilyImpl(Selector sel)471*67e74705SXin Li ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
472*67e74705SXin Li   IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
473*67e74705SXin Li   if (!first) return OMF_None;
474*67e74705SXin Li 
475*67e74705SXin Li   StringRef name = first->getName();
476*67e74705SXin Li   if (sel.isUnarySelector()) {
477*67e74705SXin Li     if (name == "autorelease") return OMF_autorelease;
478*67e74705SXin Li     if (name == "dealloc") return OMF_dealloc;
479*67e74705SXin Li     if (name == "finalize") return OMF_finalize;
480*67e74705SXin Li     if (name == "release") return OMF_release;
481*67e74705SXin Li     if (name == "retain") return OMF_retain;
482*67e74705SXin Li     if (name == "retainCount") return OMF_retainCount;
483*67e74705SXin Li     if (name == "self") return OMF_self;
484*67e74705SXin Li     if (name == "initialize") return OMF_initialize;
485*67e74705SXin Li   }
486*67e74705SXin Li 
487*67e74705SXin Li   if (name == "performSelector") return OMF_performSelector;
488*67e74705SXin Li 
489*67e74705SXin Li   // The other method families may begin with a prefix of underscores.
490*67e74705SXin Li   while (!name.empty() && name.front() == '_')
491*67e74705SXin Li     name = name.substr(1);
492*67e74705SXin Li 
493*67e74705SXin Li   if (name.empty()) return OMF_None;
494*67e74705SXin Li   switch (name.front()) {
495*67e74705SXin Li   case 'a':
496*67e74705SXin Li     if (startsWithWord(name, "alloc")) return OMF_alloc;
497*67e74705SXin Li     break;
498*67e74705SXin Li   case 'c':
499*67e74705SXin Li     if (startsWithWord(name, "copy")) return OMF_copy;
500*67e74705SXin Li     break;
501*67e74705SXin Li   case 'i':
502*67e74705SXin Li     if (startsWithWord(name, "init")) return OMF_init;
503*67e74705SXin Li     break;
504*67e74705SXin Li   case 'm':
505*67e74705SXin Li     if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
506*67e74705SXin Li     break;
507*67e74705SXin Li   case 'n':
508*67e74705SXin Li     if (startsWithWord(name, "new")) return OMF_new;
509*67e74705SXin Li     break;
510*67e74705SXin Li   default:
511*67e74705SXin Li     break;
512*67e74705SXin Li   }
513*67e74705SXin Li 
514*67e74705SXin Li   return OMF_None;
515*67e74705SXin Li }
516*67e74705SXin Li 
getInstTypeMethodFamily(Selector sel)517*67e74705SXin Li ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
518*67e74705SXin Li   IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
519*67e74705SXin Li   if (!first) return OIT_None;
520*67e74705SXin Li 
521*67e74705SXin Li   StringRef name = first->getName();
522*67e74705SXin Li 
523*67e74705SXin Li   if (name.empty()) return OIT_None;
524*67e74705SXin Li   switch (name.front()) {
525*67e74705SXin Li     case 'a':
526*67e74705SXin Li       if (startsWithWord(name, "array")) return OIT_Array;
527*67e74705SXin Li       break;
528*67e74705SXin Li     case 'd':
529*67e74705SXin Li       if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
530*67e74705SXin Li       if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
531*67e74705SXin Li       break;
532*67e74705SXin Li     case 's':
533*67e74705SXin Li       if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
534*67e74705SXin Li       if (startsWithWord(name, "standard")) return OIT_Singleton;
535*67e74705SXin Li     case 'i':
536*67e74705SXin Li       if (startsWithWord(name, "init")) return OIT_Init;
537*67e74705SXin Li     default:
538*67e74705SXin Li       break;
539*67e74705SXin Li   }
540*67e74705SXin Li   return OIT_None;
541*67e74705SXin Li }
542*67e74705SXin Li 
getStringFormatFamilyImpl(Selector sel)543*67e74705SXin Li ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) {
544*67e74705SXin Li   IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
545*67e74705SXin Li   if (!first) return SFF_None;
546*67e74705SXin Li 
547*67e74705SXin Li   StringRef name = first->getName();
548*67e74705SXin Li 
549*67e74705SXin Li   switch (name.front()) {
550*67e74705SXin Li     case 'a':
551*67e74705SXin Li       if (name == "appendFormat") return SFF_NSString;
552*67e74705SXin Li       break;
553*67e74705SXin Li 
554*67e74705SXin Li     case 'i':
555*67e74705SXin Li       if (name == "initWithFormat") return SFF_NSString;
556*67e74705SXin Li       break;
557*67e74705SXin Li 
558*67e74705SXin Li     case 'l':
559*67e74705SXin Li       if (name == "localizedStringWithFormat") return SFF_NSString;
560*67e74705SXin Li       break;
561*67e74705SXin Li 
562*67e74705SXin Li     case 's':
563*67e74705SXin Li       if (name == "stringByAppendingFormat" ||
564*67e74705SXin Li           name == "stringWithFormat") return SFF_NSString;
565*67e74705SXin Li       break;
566*67e74705SXin Li   }
567*67e74705SXin Li   return SFF_None;
568*67e74705SXin Li }
569*67e74705SXin Li 
570*67e74705SXin Li namespace {
571*67e74705SXin Li   struct SelectorTableImpl {
572*67e74705SXin Li     llvm::FoldingSet<MultiKeywordSelector> Table;
573*67e74705SXin Li     llvm::BumpPtrAllocator Allocator;
574*67e74705SXin Li   };
575*67e74705SXin Li } // end anonymous namespace.
576*67e74705SXin Li 
getSelectorTableImpl(void * P)577*67e74705SXin Li static SelectorTableImpl &getSelectorTableImpl(void *P) {
578*67e74705SXin Li   return *static_cast<SelectorTableImpl*>(P);
579*67e74705SXin Li }
580*67e74705SXin Li 
581*67e74705SXin Li SmallString<64>
constructSetterName(StringRef Name)582*67e74705SXin Li SelectorTable::constructSetterName(StringRef Name) {
583*67e74705SXin Li   SmallString<64> SetterName("set");
584*67e74705SXin Li   SetterName += Name;
585*67e74705SXin Li   SetterName[3] = toUppercase(SetterName[3]);
586*67e74705SXin Li   return SetterName;
587*67e74705SXin Li }
588*67e74705SXin Li 
589*67e74705SXin Li Selector
constructSetterSelector(IdentifierTable & Idents,SelectorTable & SelTable,const IdentifierInfo * Name)590*67e74705SXin Li SelectorTable::constructSetterSelector(IdentifierTable &Idents,
591*67e74705SXin Li                                        SelectorTable &SelTable,
592*67e74705SXin Li                                        const IdentifierInfo *Name) {
593*67e74705SXin Li   IdentifierInfo *SetterName =
594*67e74705SXin Li     &Idents.get(constructSetterName(Name->getName()));
595*67e74705SXin Li   return SelTable.getUnarySelector(SetterName);
596*67e74705SXin Li }
597*67e74705SXin Li 
getTotalMemory() const598*67e74705SXin Li size_t SelectorTable::getTotalMemory() const {
599*67e74705SXin Li   SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
600*67e74705SXin Li   return SelTabImpl.Allocator.getTotalMemory();
601*67e74705SXin Li }
602*67e74705SXin Li 
getSelector(unsigned nKeys,IdentifierInfo ** IIV)603*67e74705SXin Li Selector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) {
604*67e74705SXin Li   if (nKeys < 2)
605*67e74705SXin Li     return Selector(IIV[0], nKeys);
606*67e74705SXin Li 
607*67e74705SXin Li   SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
608*67e74705SXin Li 
609*67e74705SXin Li   // Unique selector, to guarantee there is one per name.
610*67e74705SXin Li   llvm::FoldingSetNodeID ID;
611*67e74705SXin Li   MultiKeywordSelector::Profile(ID, IIV, nKeys);
612*67e74705SXin Li 
613*67e74705SXin Li   void *InsertPos = nullptr;
614*67e74705SXin Li   if (MultiKeywordSelector *SI =
615*67e74705SXin Li         SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
616*67e74705SXin Li     return Selector(SI);
617*67e74705SXin Li 
618*67e74705SXin Li   // MultiKeywordSelector objects are not allocated with new because they have a
619*67e74705SXin Li   // variable size array (for parameter types) at the end of them.
620*67e74705SXin Li   unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
621*67e74705SXin Li   MultiKeywordSelector *SI =
622*67e74705SXin Li     (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size,
623*67e74705SXin Li                                          llvm::alignOf<MultiKeywordSelector>());
624*67e74705SXin Li   new (SI) MultiKeywordSelector(nKeys, IIV);
625*67e74705SXin Li   SelTabImpl.Table.InsertNode(SI, InsertPos);
626*67e74705SXin Li   return Selector(SI);
627*67e74705SXin Li }
628*67e74705SXin Li 
SelectorTable()629*67e74705SXin Li SelectorTable::SelectorTable() {
630*67e74705SXin Li   Impl = new SelectorTableImpl();
631*67e74705SXin Li }
632*67e74705SXin Li 
~SelectorTable()633*67e74705SXin Li SelectorTable::~SelectorTable() {
634*67e74705SXin Li   delete &getSelectorTableImpl(Impl);
635*67e74705SXin Li }
636*67e74705SXin Li 
getOperatorSpelling(OverloadedOperatorKind Operator)637*67e74705SXin Li const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
638*67e74705SXin Li   switch (Operator) {
639*67e74705SXin Li   case OO_None:
640*67e74705SXin Li   case NUM_OVERLOADED_OPERATORS:
641*67e74705SXin Li     return nullptr;
642*67e74705SXin Li 
643*67e74705SXin Li #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
644*67e74705SXin Li   case OO_##Name: return Spelling;
645*67e74705SXin Li #include "clang/Basic/OperatorKinds.def"
646*67e74705SXin Li   }
647*67e74705SXin Li 
648*67e74705SXin Li   llvm_unreachable("Invalid OverloadedOperatorKind!");
649*67e74705SXin Li }
650*67e74705SXin Li 
getNullabilitySpelling(NullabilityKind kind,bool isContextSensitive)651*67e74705SXin Li StringRef clang::getNullabilitySpelling(NullabilityKind kind,
652*67e74705SXin Li                                         bool isContextSensitive) {
653*67e74705SXin Li   switch (kind) {
654*67e74705SXin Li   case NullabilityKind::NonNull:
655*67e74705SXin Li     return isContextSensitive ? "nonnull" : "_Nonnull";
656*67e74705SXin Li 
657*67e74705SXin Li   case NullabilityKind::Nullable:
658*67e74705SXin Li     return isContextSensitive ? "nullable" : "_Nullable";
659*67e74705SXin Li 
660*67e74705SXin Li   case NullabilityKind::Unspecified:
661*67e74705SXin Li     return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
662*67e74705SXin Li   }
663*67e74705SXin Li   llvm_unreachable("Unknown nullability kind.");
664*67e74705SXin Li }
665