blob: 4f85fca53868c9a1ef037cbbeda81af6cd5b11f4 [file] [log] [blame]
Douglas Gregor2e1cd422008-11-17 14:58:09 +00001//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the DeclarationName and DeclarationNameTable
11// classes.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/AST/DeclarationName.h"
Douglas Gregor10bd3682008-11-17 22:58:34 +000015#include "clang/AST/Type.h"
Douglas Gregord6b5f132009-11-04 22:24:30 +000016#include "clang/AST/TypeOrdering.h"
Douglas Gregor10bd3682008-11-17 22:58:34 +000017#include "clang/AST/Decl.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000018#include "clang/Basic/IdentifierTable.h"
Douglas Gregor370187c2009-04-22 21:45:53 +000019#include "llvm/ADT/DenseMap.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000020#include "llvm/ADT/FoldingSet.h"
Benjamin Kramerf6cde772010-04-17 09:56:45 +000021#include "llvm/Support/raw_ostream.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000022using namespace clang;
23
24namespace clang {
25/// CXXSpecialName - Records the type associated with one of the
26/// "special" kinds of declaration names in C++, e.g., constructors,
27/// destructors, and conversion functions.
Mike Stump1eb44332009-09-09 15:08:12 +000028class CXXSpecialName
Douglas Gregor2e1cd422008-11-17 14:58:09 +000029 : public DeclarationNameExtra, public llvm::FoldingSetNode {
30public:
Douglas Gregor2def4832008-11-17 20:34:05 +000031 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000032 QualType Type;
33
Douglas Gregor2def4832008-11-17 20:34:05 +000034 /// FETokenInfo - Extra information associated with this declaration
35 /// name that can be used by the front end.
36 void *FETokenInfo;
37
Douglas Gregor2e1cd422008-11-17 14:58:09 +000038 void Profile(llvm::FoldingSetNodeID &ID) {
39 ID.AddInteger(ExtraKindOrNumArgs);
40 ID.AddPointer(Type.getAsOpaquePtr());
41 }
42};
43
Douglas Gregore94ca9e42008-11-18 14:39:36 +000044/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump1eb44332009-09-09 15:08:12 +000045/// overloaded operator in C++, such as "operator+.
Douglas Gregore94ca9e42008-11-18 14:39:36 +000046class CXXOperatorIdName : public DeclarationNameExtra {
47public:
48 /// FETokenInfo - Extra information associated with this operator
49 /// name that can be used by the front end.
50 void *FETokenInfo;
51};
52
Sean Hunt3e518bd2009-11-29 07:34:05 +000053/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
54/// name.
55///
56/// This identifier is stored here rather than directly in DeclarationName so as
57/// to allow Objective-C selectors, which are about a million times more common,
58/// to consume minimal memory.
Sean Hunta6c058d2010-01-13 09:01:02 +000059class CXXLiteralOperatorIdName
60 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Sean Hunt3e518bd2009-11-29 07:34:05 +000061public:
62 IdentifierInfo *ID;
Sean Hunta6c058d2010-01-13 09:01:02 +000063
64 void Profile(llvm::FoldingSetNodeID &FSID) {
65 FSID.AddPointer(ID);
66 }
Sean Hunt3e518bd2009-11-29 07:34:05 +000067};
68
John McCall7fe0b9e2010-02-13 01:04:05 +000069static int compareInt(unsigned A, unsigned B) {
70 return (A < B ? -1 : (A > B ? 1 : 0));
71}
72
73int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000074 if (LHS.getNameKind() != RHS.getNameKind())
John McCall7fe0b9e2010-02-13 01:04:05 +000075 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregord6b5f132009-11-04 22:24:30 +000076
77 switch (LHS.getNameKind()) {
John McCall7fe0b9e2010-02-13 01:04:05 +000078 case DeclarationName::Identifier: {
79 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
80 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
81 if (!LII) return RII ? -1 : 0;
82 if (!RII) return 1;
83
84 return LII->getName().compare(RII->getName());
85 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +000086
Douglas Gregord6b5f132009-11-04 22:24:30 +000087 case DeclarationName::ObjCZeroArgSelector:
88 case DeclarationName::ObjCOneArgSelector:
89 case DeclarationName::ObjCMultiArgSelector: {
90 Selector LHSSelector = LHS.getObjCSelector();
91 Selector RHSSelector = RHS.getObjCSelector();
John McCall7fe0b9e2010-02-13 01:04:05 +000092 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
93 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000094 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
95 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
Douglas Gregord6b5f132009-11-04 22:24:30 +000096
97 switch (LHSId->getName().compare(RHSId->getName())) {
98 case -1: return true;
99 case 1: return false;
100 default: break;
101 }
102 }
John McCall7fe0b9e2010-02-13 01:04:05 +0000103
104 return compareInt(LN, RN);
Douglas Gregord6b5f132009-11-04 22:24:30 +0000105 }
106
107 case DeclarationName::CXXConstructorName:
108 case DeclarationName::CXXDestructorName:
109 case DeclarationName::CXXConversionFunctionName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000110 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
111 return -1;
112 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
113 return 1;
114 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000115
116 case DeclarationName::CXXOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000117 return compareInt(LHS.getCXXOverloadedOperator(),
118 RHS.getCXXOverloadedOperator());
Sean Hunt3e518bd2009-11-29 07:34:05 +0000119
120 case DeclarationName::CXXLiteralOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000121 return LHS.getCXXLiteralIdentifier()->getName().compare(
122 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregord6b5f132009-11-04 22:24:30 +0000123
124 case DeclarationName::CXXUsingDirective:
John McCall7fe0b9e2010-02-13 01:04:05 +0000125 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000126 }
127
John McCall7fe0b9e2010-02-13 01:04:05 +0000128 return 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000129}
130
131} // end namespace clang
132
133DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000134 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000135 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000136 return;
137 }
138
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000139 switch (Sel.getNumArgs()) {
140 case 0:
141 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000142 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000143 Ptr |= StoredObjCZeroArgSelector;
144 break;
145
146 case 1:
147 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000148 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000149 Ptr |= StoredObjCOneArgSelector;
150 break;
151
152 default:
153 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000154 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000155 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000156 break;
157 }
158}
159
160DeclarationName::NameKind DeclarationName::getNameKind() const {
161 switch (getStoredNameKind()) {
162 case StoredIdentifier: return Identifier;
163 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
164 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
165
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000166 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000167 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000168 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000169 return CXXConstructorName;
170
Mike Stump1eb44332009-09-09 15:08:12 +0000171 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000172 return CXXDestructorName;
173
Mike Stump1eb44332009-09-09 15:08:12 +0000174 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000175 return CXXConversionFunctionName;
176
Sean Hunt3e518bd2009-11-29 07:34:05 +0000177 case DeclarationNameExtra::CXXLiteralOperator:
178 return CXXLiteralOperatorName;
179
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000180 case DeclarationNameExtra::CXXUsingDirective:
181 return CXXUsingDirective;
182
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000183 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000184 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000185 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000186 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000187 return CXXOperatorName;
188
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000189 return ObjCMultiArgSelector;
190 }
191 break;
192 }
193
194 // Can't actually get here.
Chris Lattnerac8d75f2009-03-21 06:40:50 +0000195 assert(0 && "This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000196 return Identifier;
197}
198
Douglas Gregor48026d22010-01-11 18:40:55 +0000199bool DeclarationName::isDependentName() const {
200 QualType T = getCXXNameType();
201 return !T.isNull() && T->isDependentType();
202}
203
Douglas Gregor10bd3682008-11-17 22:58:34 +0000204std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000205 std::string Result;
206 llvm::raw_string_ostream OS(Result);
207 printName(OS);
208 return OS.str();
209}
210
211void DeclarationName::printName(llvm::raw_ostream &OS) const {
Douglas Gregor10bd3682008-11-17 22:58:34 +0000212 switch (getNameKind()) {
213 case Identifier:
214 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000215 OS << II->getName();
216 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000217
218 case ObjCZeroArgSelector:
219 case ObjCOneArgSelector:
220 case ObjCMultiArgSelector:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000221 OS << getObjCSelector().getAsString();
222 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000223
224 case CXXConstructorName: {
225 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000226 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000227 OS << ClassRec->getDecl();
228 else
229 OS << ClassType.getAsString();
230 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000231 }
232
233 case CXXDestructorName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000234 OS << '~';
Douglas Gregor10bd3682008-11-17 22:58:34 +0000235 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000236 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000237 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000238 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000239 OS << Type.getAsString();
240 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000241 }
242
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000243 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000244 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000245 0,
246#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
247 Spelling,
248#include "clang/Basic/OperatorKinds.def"
249 };
250 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
251 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000252
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000253 OS << "operator";
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000254 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000255 OS << ' ';
256 OS << OpName;
257 return;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000258 }
259
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000260 case CXXLiteralOperatorName:
261 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
262 return;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000263
Douglas Gregor10bd3682008-11-17 22:58:34 +0000264 case CXXConversionFunctionName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000265 OS << "operator ";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000266 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000267 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000268 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000269 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000270 OS << Type.getAsString();
271 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000272 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000273 case CXXUsingDirective:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000274 OS << "<using-directive>";
275 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000276 }
277
278 assert(false && "Unexpected declaration name kind");
Douglas Gregor10bd3682008-11-17 22:58:34 +0000279}
280
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000281QualType DeclarationName::getCXXNameType() const {
282 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
283 return CXXName->Type;
284 else
285 return QualType();
286}
287
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000288OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
289 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000290 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000291 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
292 return static_cast<OverloadedOperatorKind>(value);
293 } else {
294 return OO_None;
295 }
296}
297
Sean Hunt3e518bd2009-11-29 07:34:05 +0000298IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
299 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
300 return CXXLit->ID;
301 else
302 return 0;
303}
304
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000305Selector DeclarationName::getObjCSelector() const {
306 switch (getNameKind()) {
307 case ObjCZeroArgSelector:
308 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
309
310 case ObjCOneArgSelector:
311 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
312
313 case ObjCMultiArgSelector:
314 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
315
316 default:
317 break;
318 }
319
320 return Selector();
321}
322
Douglas Gregor2def4832008-11-17 20:34:05 +0000323void *DeclarationName::getFETokenInfoAsVoid() const {
324 switch (getNameKind()) {
325 case Identifier:
326 return getAsIdentifierInfo()->getFETokenInfo<void>();
327
328 case CXXConstructorName:
329 case CXXDestructorName:
330 case CXXConversionFunctionName:
331 return getAsCXXSpecialName()->FETokenInfo;
332
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000333 case CXXOperatorName:
334 return getAsCXXOperatorIdName()->FETokenInfo;
335
Sean Hunt3e518bd2009-11-29 07:34:05 +0000336 case CXXLiteralOperatorName:
337 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
338
Douglas Gregor2def4832008-11-17 20:34:05 +0000339 default:
340 assert(false && "Declaration name has no FETokenInfo");
341 }
342 return 0;
343}
344
345void DeclarationName::setFETokenInfo(void *T) {
346 switch (getNameKind()) {
347 case Identifier:
348 getAsIdentifierInfo()->setFETokenInfo(T);
349 break;
350
351 case CXXConstructorName:
352 case CXXDestructorName:
353 case CXXConversionFunctionName:
354 getAsCXXSpecialName()->FETokenInfo = T;
355 break;
356
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000357 case CXXOperatorName:
358 getAsCXXOperatorIdName()->FETokenInfo = T;
359 break;
360
Sean Hunt3e518bd2009-11-29 07:34:05 +0000361 case CXXLiteralOperatorName:
362 getCXXLiteralIdentifier()->setFETokenInfo(T);
363 break;
364
Douglas Gregor2def4832008-11-17 20:34:05 +0000365 default:
366 assert(false && "Declaration name has no FETokenInfo");
367 }
368}
369
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000370DeclarationName DeclarationName::getUsingDirectiveName() {
371 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000372 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000373 { DeclarationNameExtra::CXXUsingDirective };
374
375 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
376 Ptr |= StoredDeclarationNameExtra;
377
378 return DeclarationName(Ptr);
379}
380
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000381void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000382 printName(llvm::errs());
383 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000384}
385
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000386DeclarationNameTable::DeclarationNameTable() {
387 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000388 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000389
390 // Initialize the overloaded operator names.
391 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
392 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000393 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000394 = Op + DeclarationNameExtra::CXXConversionFunction;
395 CXXOperatorNames[Op].FETokenInfo = 0;
396 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000397}
398
399DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000400 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000401 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000402 llvm::FoldingSetIterator<CXXSpecialName>
403 SI = SpecialNames->begin(), SE = SpecialNames->end();
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000404
Sean Hunta6c058d2010-01-13 09:01:02 +0000405 while (SI != SE) {
406 CXXSpecialName *n = &*SI++;
Nuno Lopesf9d1e4b2008-12-14 21:53:25 +0000407 delete n;
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000408 }
409
Sean Hunta6c058d2010-01-13 09:01:02 +0000410
411 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
412 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
413 (CXXLiteralOperatorNames);
414 llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
415 LI = LiteralNames->begin(), LE = LiteralNames->end();
416
417 while (LI != LE) {
418 CXXLiteralOperatorIdName *n = &*LI++;
419 delete n;
420 }
421
422 delete SpecialNames;
423 delete LiteralNames;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000424 delete [] CXXOperatorNames;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000425}
426
Mike Stump1eb44332009-09-09 15:08:12 +0000427DeclarationName
428DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000429 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000430 assert(Kind >= DeclarationName::CXXConstructorName &&
431 Kind <= DeclarationName::CXXConversionFunctionName &&
432 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000433 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000434 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
435
436 DeclarationNameExtra::ExtraKind EKind;
437 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000438 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000439 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000440 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000441 break;
442 case DeclarationName::CXXDestructorName:
443 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000444 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000445 break;
446 case DeclarationName::CXXConversionFunctionName:
447 EKind = DeclarationNameExtra::CXXConversionFunction;
448 break;
449 default:
450 return DeclarationName();
451 }
452
453 // Unique selector, to guarantee there is one per name.
454 llvm::FoldingSetNodeID ID;
455 ID.AddInteger(EKind);
456 ID.AddPointer(Ty.getAsOpaquePtr());
457
458 void *InsertPos = 0;
459 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
460 return DeclarationName(Name);
461
462 CXXSpecialName *SpecialName = new CXXSpecialName;
463 SpecialName->ExtraKindOrNumArgs = EKind;
464 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000465 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000466
467 SpecialNames->InsertNode(SpecialName, InsertPos);
468 return DeclarationName(SpecialName);
469}
470
Mike Stump1eb44332009-09-09 15:08:12 +0000471DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000472DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
473 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
474}
475
Sean Hunt3e518bd2009-11-29 07:34:05 +0000476DeclarationName
477DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000478 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
479 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
480 (CXXLiteralOperatorNames);
481
482 llvm::FoldingSetNodeID ID;
483 ID.AddPointer(II);
484
485 void *InsertPos = 0;
486 if (CXXLiteralOperatorIdName *Name =
487 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
488 return DeclarationName (Name);
489
Sean Hunt3e518bd2009-11-29 07:34:05 +0000490 CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
491 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
492 LiteralName->ID = II;
Sean Hunta6c058d2010-01-13 09:01:02 +0000493
494 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000495 return DeclarationName(LiteralName);
496}
497
Mike Stump1eb44332009-09-09 15:08:12 +0000498unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000499llvm::DenseMapInfo<clang::DeclarationName>::
500getHashValue(clang::DeclarationName N) {
501 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
502}
503