blob: 30a8595932a289bbfde941ad35d7a200c78a3def [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 +000018#include <iostream>
19using namespace llvm;
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
Chris Lattnerc79f6fb2006-07-04 17:53:21 +000023// IdentifierInfo Implementation
Chris Lattner22eb9722006-06-18 05:43:12 +000024//===----------------------------------------------------------------------===//
25
Chris Lattner3bc804e2006-10-28 23:46:24 +000026IdentifierInfo::IdentifierInfo() {
27 Macro = 0;
28 TokenID = tok::identifier;
29 PPID = tok::pp_not_keyword;
30 ObjCID = tok::objc_not_keyword;
31 IsExtension = false;
32 IsPoisoned = false;
33 IsOtherTargetMacro = false;
34 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 Lattner22eb9722006-06-18 05:43:12 +000048
Chris Lattner2b9e19b2006-10-29 23:43:13 +000049 IdentifierInfo &Def = get("define");
50
Chris Lattnerf2e3ac32006-10-27 03:59:10 +000051 // Populate the identifier table with info about keywords for the current
52 // language.
Chris Lattner25e0d542006-10-18 06:07:05 +000053 AddKeywords(LangOpts);
Chris Lattner22eb9722006-06-18 05:43:12 +000054
Chris Lattner2b9e19b2006-10-29 23:43:13 +000055 IdentifierInfo &Def2 = get("define");
Chris Lattner22eb9722006-06-18 05:43:12 +000056
Chris Lattner2b9e19b2006-10-29 23:43:13 +000057 std::cerr << "FOO\n";
Chris Lattner91cbf112006-07-03 04:28:52 +000058}
Chris Lattner22eb9722006-06-18 05:43:12 +000059
Chris Lattner25e0d542006-10-18 06:07:05 +000060//===----------------------------------------------------------------------===//
61// Language Keyword Implementation
62//===----------------------------------------------------------------------===//
63
64/// AddKeyword - This method is used to associate a token ID with specific
65/// identifiers because they are language keywords. This causes the lexer to
66/// automatically map matching identifiers to specialized token codes.
67///
68/// The C90/C99/CPP flags are set to 0 if the token should be enabled in the
69/// specified langauge, set to 1 if it is an extension in the specified
70/// language, and set to 2 if disabled in the specified language.
Chris Lattner2b9e19b2006-10-29 23:43:13 +000071static void AddKeyword(const char *Keyword, unsigned KWLen,
72 tok::TokenKind TokenCode,
Chris Lattnera4271e42006-10-20 06:13:26 +000073 int C90, int C99, int CXX,
Chris Lattner25e0d542006-10-18 06:07:05 +000074 const LangOptions &LangOpts, IdentifierTable &Table) {
Chris Lattnera4271e42006-10-20 06:13:26 +000075 int Flags = LangOpts.CPlusPlus ? CXX : (LangOpts.C99 ? C99 : C90);
Chris Lattner25e0d542006-10-18 06:07:05 +000076
77 // Don't add this keyword if disabled in this language or if an extension
78 // and extensions are disabled.
79 if (Flags + LangOpts.NoExtensions >= 2) return;
80
Chris Lattner2b9e19b2006-10-29 23:43:13 +000081 IdentifierInfo &Info = Table.get(Keyword, Keyword+KWLen);
Chris Lattner25e0d542006-10-18 06:07:05 +000082 Info.setTokenID(TokenCode);
83 Info.setIsExtensionToken(Flags == 1);
84}
85
86/// AddPPKeyword - Register a preprocessor keyword like "define" "undef" or
87/// "elif".
88static void AddPPKeyword(tok::PPKeywordKind PPID,
89 const char *Name, unsigned NameLen,
90 IdentifierTable &Table) {
91 Table.get(Name, Name+NameLen).setPPKeywordID(PPID);
92}
93
94/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or
95/// "property".
96static void AddObjCKeyword(tok::ObjCKeywordKind ObjCID,
97 const char *Name, unsigned NameLen,
98 IdentifierTable &Table) {
99 Table.get(Name, Name+NameLen).setObjCKeywordID(ObjCID);
100}
101
102/// AddKeywords - Add all keywords to the symbol table.
103///
104void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
105 enum {
106 C90Shift = 0,
107 EXTC90 = 1 << C90Shift,
108 NOTC90 = 2 << C90Shift,
109 C99Shift = 2,
110 EXTC99 = 1 << C99Shift,
111 NOTC99 = 2 << C99Shift,
112 CPPShift = 4,
113 EXTCPP = 1 << CPPShift,
114 NOTCPP = 2 << CPPShift,
115 Mask = 3
116 };
117
118 // Add keywords and tokens for the current language.
119#define KEYWORD(NAME, FLAGS) \
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000120 AddKeyword(#NAME, strlen(#NAME), tok::kw_ ## NAME, \
Chris Lattner25e0d542006-10-18 06:07:05 +0000121 ((FLAGS) >> C90Shift) & Mask, \
122 ((FLAGS) >> C99Shift) & Mask, \
123 ((FLAGS) >> CPPShift) & Mask, LangOpts, *this);
124#define ALIAS(NAME, TOK) \
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000125 AddKeyword(NAME, strlen(NAME), tok::kw_ ## TOK, 0, 0, 0, LangOpts, *this);
Chris Lattner25e0d542006-10-18 06:07:05 +0000126#define PPKEYWORD(NAME) \
127 AddPPKeyword(tok::pp_##NAME, #NAME, strlen(#NAME), *this);
128#define OBJC1_AT_KEYWORD(NAME) \
129 if (LangOpts.ObjC1) \
130 AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
131#define OBJC2_AT_KEYWORD(NAME) \
132 if (LangOpts.ObjC2) \
133 AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this);
134#include "clang/Basic/TokenKinds.def"
135}
136
137
138//===----------------------------------------------------------------------===//
139// Stats Implementation
140//===----------------------------------------------------------------------===//
141
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000142class StatsVisitor : public CStringMapVisitor {
143 unsigned &IDLenTotal;
144 unsigned &MaxIDLen;
145public:
146 StatsVisitor(unsigned &idLenTotal, unsigned &maxIDLen)
147 : IDLenTotal(idLenTotal), MaxIDLen(maxIDLen) {}
148 void Visit(const char *Key, void *Value) const {
149 unsigned IdLen = strlen(Key);
150 IDLenTotal += IdLen;
151 if (MaxIDLen < IdLen)
152 MaxIDLen = IdLen;
153 }
154};
155
156
Chris Lattner22eb9722006-06-18 05:43:12 +0000157/// PrintStats - Print statistics about how well the identifier table is doing
158/// at hashing identifiers.
159void IdentifierTable::PrintStats() const {
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000160 unsigned NumBuckets = HashTable.getNumBuckets();
161 unsigned NumIdentifiers = HashTable.getNumItems();
162 unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
Chris Lattner22eb9722006-06-18 05:43:12 +0000163 unsigned AverageIdentifierSize = 0;
164 unsigned MaxIdentifierLength = 0;
165
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000166 // TODO: Figure out maximum times an identifier had to probe for -stats.
167 HashTable.VisitEntries(StatsVisitor(AverageIdentifierSize,
168 MaxIdentifierLength));
Chris Lattner22eb9722006-06-18 05:43:12 +0000169
170 std::cerr << "\n*** Identifier Table Stats:\n";
171 std::cerr << "# Identifiers: " << NumIdentifiers << "\n";
172 std::cerr << "# Empty Buckets: " << NumEmptyBuckets << "\n";
Chris Lattner22eb9722006-06-18 05:43:12 +0000173 std::cerr << "Hash density (#identifiers per bucket): "
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000174 << NumIdentifiers/(double)NumBuckets << "\n";
Chris Lattner22eb9722006-06-18 05:43:12 +0000175 std::cerr << "Ave identifier length: "
176 << (AverageIdentifierSize/(double)NumIdentifiers) << "\n";
177 std::cerr << "Max identifier length: " << MaxIdentifierLength << "\n";
178
179 // Compute statistics about the memory allocated for identifiers.
Chris Lattner2b9e19b2006-10-29 23:43:13 +0000180 HashTable.getAllocator().PrintStats();
Chris Lattner22eb9722006-06-18 05:43:12 +0000181}
182
183