blob: 4c6516df2d38707a7f8d2246ba02fd6142367994 [file] [log] [blame]
Chris Lattnerec659fc2006-10-29 22:09:44 +00001//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
Chris Lattner22eb9722006-06-18 05:43:12 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnerc79f6fb2006-07-04 17:53:21 +000010// This file implements the IdentifierInfo, IdentifierVisitor, and
Chris Lattner91cbf112006-07-03 04:28:52 +000011// IdentifierTable interfaces.
Chris Lattner22eb9722006-06-18 05:43:12 +000012//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Lex/IdentifierTable.h"
16#include "clang/Lex/MacroInfo.h"
Chris Lattner25e0d542006-10-18 06:07:05 +000017#include "clang/Basic/LangOptions.h"
Chris Lattner22eb9722006-06-18 05:43:12 +000018using namespace clang;
19
20//===----------------------------------------------------------------------===//
Chris Lattnerc79f6fb2006-07-04 17:53:21 +000021// IdentifierInfo Implementation
Chris Lattner22eb9722006-06-18 05:43:12 +000022//===----------------------------------------------------------------------===//
23
Chris Lattner3bc804e2006-10-28 23:46:24 +000024IdentifierInfo::IdentifierInfo() {
25 Macro = 0;
26 TokenID = tok::identifier;
27 PPID = tok::pp_not_keyword;
28 ObjCID = tok::objc_not_keyword;
Chris Lattner9561a0b2007-01-28 08:20:04 +000029 BuiltinID = 0;
Chris Lattner3bc804e2006-10-28 23:46:24 +000030 IsExtension = false;
31 IsPoisoned = false;
32 IsOtherTargetMacro = false;
Chris Lattner5b9f4892006-11-21 17:23:33 +000033 IsCPPOperatorKeyword = false;
Chris Lattner3bc804e2006-10-28 23:46:24 +000034 FETokenInfo = 0;
35}
36
37IdentifierInfo::~IdentifierInfo() {
Chris Lattner22eb9722006-06-18 05:43:12 +000038 delete Macro;
39}
40
Chris Lattner91cbf112006-07-03 04:28:52 +000041//===----------------------------------------------------------------------===//
Chris Lattner22eb9722006-06-18 05:43:12 +000042// IdentifierTable Implementation
43//===----------------------------------------------------------------------===//
44
Chris Lattner2b9e19b2006-10-29 23:43:13 +000045IdentifierTable::IdentifierTable(const LangOptions &LangOpts)
46 // Start with space for 8K identifiers.
47 : HashTable(8192) {
Chris Lattnerda933aa2006-10-29 23:49:15 +000048
Chris Lattnerf2e3ac32006-10-27 03:59:10 +000049 // Populate the identifier table with info about keywords for the current
50 // language.
Chris Lattner25e0d542006-10-18 06:07:05 +000051 AddKeywords(LangOpts);
Chris Lattner91cbf112006-07-03 04:28:52 +000052}
Chris Lattner22eb9722006-06-18 05:43:12 +000053
Chris Lattner25e0d542006-10-18 06:07:05 +000054//===----------------------------------------------------------------------===//
55// Language Keyword Implementation
56//===----------------------------------------------------------------------===//
57
58/// AddKeyword - This method is used to associate a token ID with specific
59/// identifiers because they are language keywords. This causes the lexer to
60/// automatically map matching identifiers to specialized token codes.
61///
Chris Lattner539007a2007-07-16 04:18:29 +000062/// The C90/C99/CPP/CPP0x flags are set to 0 if the token should be
63/// enabled in the specified langauge, set to 1 if it is an extension
64/// in the specified language, and set to 2 if disabled in the
65/// specified language.
Chris Lattner2b9e19b2006-10-29 23:43:13 +000066static void AddKeyword(const char *Keyword, unsigned KWLen,
67 tok::TokenKind TokenCode,
Chris Lattner539007a2007-07-16 04:18:29 +000068 int C90, int C99, int CXX, int CXX0x,
Chris Lattner25e0d542006-10-18 06:07:05 +000069 const LangOptions &LangOpts, IdentifierTable &Table) {
Chris Lattner539007a2007-07-16 04:18:29 +000070 int Flags = LangOpts.CPlusPlus ? (LangOpts.CPlusPlus0x? CXX0x : CXX)
71 : (LangOpts.C99 ? C99 : C90);
Chris Lattner25e0d542006-10-18 06:07:05 +000072
73 // Don't add this keyword if disabled in this language or if an extension
74 // and extensions are disabled.
75 if (Flags + LangOpts.NoExtensions >= 2) return;
76
Chris Lattner2b9e19b2006-10-29 23:43:13 +000077 IdentifierInfo &Info = Table.get(Keyword, Keyword+KWLen);
Chris Lattner25e0d542006-10-18 06:07:05 +000078 Info.setTokenID(TokenCode);
79 Info.setIsExtensionToken(Flags == 1);
80}
81
Chris Lattnere8b27242007-06-08 17:27:55 +000082static void AddAlias(const char *Keyword, unsigned KWLen,
83 const char *AliaseeKeyword, unsigned AliaseeKWLen,
84 const LangOptions &LangOpts, IdentifierTable &Table) {
85 IdentifierInfo &AliasInfo = Table.get(Keyword, Keyword+KWLen);
86 IdentifierInfo &AliaseeInfo = Table.get(AliaseeKeyword,
87 AliaseeKeyword+AliaseeKWLen);
88 AliasInfo.setTokenID(AliaseeInfo.getTokenID());
89 AliasInfo.setIsExtensionToken(AliaseeInfo.isExtensionToken());
90}
91
Chris Lattner25e0d542006-10-18 06:07:05 +000092/// AddPPKeyword - Register a preprocessor keyword like "define" "undef" or
93/// "elif".
94static void AddPPKeyword(tok::PPKeywordKind PPID,
95 const char *Name, unsigned NameLen,
96 IdentifierTable &Table) {
97 Table.get(Name, Name+NameLen).setPPKeywordID(PPID);
98}
99
Chris Lattner5b9f4892006-11-21 17:23:33 +0000100/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
101/// representations.
102static void AddCXXOperatorKeyword(const char *Keyword, unsigned KWLen,
103 tok::TokenKind TokenCode,
104 IdentifierTable &Table) {
105 IdentifierInfo &Info = Table.get(Keyword, Keyword + KWLen);
106 Info.setTokenID(TokenCode);
107 Info.setIsCPlusplusOperatorKeyword();
108}
109
Chris Lattner25e0d542006-10-18 06:07:05 +0000110/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or
111/// "property".
112static void AddObjCKeyword(tok::ObjCKeywordKind ObjCID,
113 const char *Name, unsigned NameLen,
114 IdentifierTable &Table) {
115 Table.get(Name, Name+NameLen).setObjCKeywordID(ObjCID);
116}
117
118/// AddKeywords - Add all keywords to the symbol table.
119///
120void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
121 enum {
122 C90Shift = 0,
123 EXTC90 = 1 << C90Shift,
124 NOTC90 = 2 << C90Shift,
125 C99Shift = 2,
126 EXTC99 = 1 << C99Shift,
127 NOTC99 = 2 << C99Shift,
128 CPPShift = 4,
129 EXTCPP = 1 << CPPShift,
130 NOTCPP = 2 << CPPShift,
Chris Lattner539007a2007-07-16 04:18:29 +0000131 CPP0xShift = 6,
132 EXTCPP0x = 1 << CPP0xShift,
133 NOTCPP0x = 2 << CPP0xShift,
Chris Lattner25e0d542006-10-18 06:07:05 +0000134 Mask = 3
135 };
136
137 // Add keywords and tokens for the current language.
138#define KEYWORD(NAME, FLAGS) \
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000139 AddKeyword(#NAME, strlen(#NAME), tok::kw_ ## NAME, \
Chris Lattner25e0d542006-10-18 06:07:05 +0000140 ((FLAGS) >> C90Shift) & Mask, \
141 ((FLAGS) >> C99Shift) & Mask, \
Chris Lattner539007a2007-07-16 04:18:29 +0000142 ((FLAGS) >> CPPShift) & Mask, \
143 ((FLAGS) >> CPP0xShift) & Mask, LangOpts, *this);
Chris Lattner25e0d542006-10-18 06:07:05 +0000144#define ALIAS(NAME, TOK) \
Chris Lattnere8b27242007-06-08 17:27:55 +0000145 AddAlias(NAME, strlen(NAME), #TOK, strlen(#TOK), LangOpts, *this);
Chris Lattner25e0d542006-10-18 06:07:05 +0000146#define PPKEYWORD(NAME) \
147 AddPPKeyword(tok::pp_##NAME, #NAME, strlen(#NAME), *this);
Chris Lattner5b9f4892006-11-21 17:23:33 +0000148#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
Chris Lattner3e7592e2006-12-04 07:48:37 +0000149 if (LangOpts.CXXOperatorNames) \
Chris Lattner5b9f4892006-11-21 17:23:33 +0000150 AddCXXOperatorKeyword(#NAME, strlen(#NAME), tok::ALIAS, *this);
Chris Lattner25e0d542006-10-18 06:07:05 +0000151#define OBJC1_AT_KEYWORD(NAME) \
152 if (LangOpts.ObjC1) \
153 AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
154#define OBJC2_AT_KEYWORD(NAME) \
155 if (LangOpts.ObjC2) \
156 AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
157#include "clang/Basic/TokenKinds.def"
158}
159
160
161//===----------------------------------------------------------------------===//
162// Stats Implementation
163//===----------------------------------------------------------------------===//
164
Chris Lattner22eb9722006-06-18 05:43:12 +0000165/// PrintStats - Print statistics about how well the identifier table is doing
166/// at hashing identifiers.
167void IdentifierTable::PrintStats() const {
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000168 unsigned NumBuckets = HashTable.getNumBuckets();
169 unsigned NumIdentifiers = HashTable.getNumItems();
170 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
Chris Lattner22eb9722006-06-18 05:43:12 +0000171 unsigned AverageIdentifierSize = 0;
172 unsigned MaxIdentifierLength = 0;
173
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000174 // TODO: Figure out maximum times an identifier had to probe for -stats.
Chris Lattner23b7eb62007-06-15 23:05:46 +0000175 for (llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator>::const_iterator
Chris Lattnerb055f2d2007-02-11 08:19:57 +0000176 I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
177 unsigned IdLen = I->getKeyLength();
178 AverageIdentifierSize += IdLen;
179 if (MaxIdentifierLength < IdLen)
180 MaxIdentifierLength = IdLen;
181 }
Chris Lattner22eb9722006-06-18 05:43:12 +0000182
Chris Lattner23b7eb62007-06-15 23:05:46 +0000183 fprintf(stderr, "\n*** Identifier Table Stats:\n");
184 fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers);
185 fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
186 fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
187 NumIdentifiers/(double)NumBuckets);
188 fprintf(stderr, "Ave identifier length: %f\n",
189 (AverageIdentifierSize/(double)NumIdentifiers));
190 fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);
Chris Lattner22eb9722006-06-18 05:43:12 +0000191
192 // Compute statistics about the memory allocated for identifiers.
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000193 HashTable.getAllocator().PrintStats();
Chris Lattner22eb9722006-06-18 05:43:12 +0000194}