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