blob: 343d403e76ad6ca808905072ec07935454b54507 [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//===----------------------------------------------------------------------===//
Ted Kremenekac9590e2010-05-10 20:40:08 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000016#include "clang/AST/DeclarationName.h"
Douglas Gregor10bd3682008-11-17 22:58:34 +000017#include "clang/AST/Type.h"
Douglas Gregord6b5f132009-11-04 22:24:30 +000018#include "clang/AST/TypeOrdering.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000019#include "clang/Basic/IdentifierTable.h"
Douglas Gregor370187c2009-04-22 21:45:53 +000020#include "llvm/ADT/DenseMap.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000021#include "llvm/ADT/FoldingSet.h"
Benjamin Kramerf6cde772010-04-17 09:56:45 +000022#include "llvm/Support/raw_ostream.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000023using namespace clang;
24
25namespace clang {
26/// CXXSpecialName - Records the type associated with one of the
27/// "special" kinds of declaration names in C++, e.g., constructors,
28/// destructors, and conversion functions.
Mike Stump1eb44332009-09-09 15:08:12 +000029class CXXSpecialName
Douglas Gregor2e1cd422008-11-17 14:58:09 +000030 : public DeclarationNameExtra, public llvm::FoldingSetNode {
31public:
Douglas Gregor2def4832008-11-17 20:34:05 +000032 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000033 QualType Type;
34
Douglas Gregor2def4832008-11-17 20:34:05 +000035 /// FETokenInfo - Extra information associated with this declaration
36 /// name that can be used by the front end.
37 void *FETokenInfo;
38
Douglas Gregor2e1cd422008-11-17 14:58:09 +000039 void Profile(llvm::FoldingSetNodeID &ID) {
40 ID.AddInteger(ExtraKindOrNumArgs);
41 ID.AddPointer(Type.getAsOpaquePtr());
42 }
43};
44
Douglas Gregore94ca9e42008-11-18 14:39:36 +000045/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump1eb44332009-09-09 15:08:12 +000046/// overloaded operator in C++, such as "operator+.
Douglas Gregore94ca9e42008-11-18 14:39:36 +000047class CXXOperatorIdName : public DeclarationNameExtra {
48public:
49 /// FETokenInfo - Extra information associated with this operator
50 /// name that can be used by the front end.
51 void *FETokenInfo;
52};
53
Sean Hunt3e518bd2009-11-29 07:34:05 +000054/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
55/// name.
56///
57/// This identifier is stored here rather than directly in DeclarationName so as
58/// to allow Objective-C selectors, which are about a million times more common,
59/// to consume minimal memory.
Sean Hunta6c058d2010-01-13 09:01:02 +000060class CXXLiteralOperatorIdName
61 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Sean Hunt3e518bd2009-11-29 07:34:05 +000062public:
63 IdentifierInfo *ID;
Sean Hunta6c058d2010-01-13 09:01:02 +000064
65 void Profile(llvm::FoldingSetNodeID &FSID) {
66 FSID.AddPointer(ID);
67 }
Sean Hunt3e518bd2009-11-29 07:34:05 +000068};
69
John McCall7fe0b9e2010-02-13 01:04:05 +000070static int compareInt(unsigned A, unsigned B) {
71 return (A < B ? -1 : (A > B ? 1 : 0));
72}
73
74int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000075 if (LHS.getNameKind() != RHS.getNameKind())
John McCall7fe0b9e2010-02-13 01:04:05 +000076 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregord6b5f132009-11-04 22:24:30 +000077
78 switch (LHS.getNameKind()) {
John McCall7fe0b9e2010-02-13 01:04:05 +000079 case DeclarationName::Identifier: {
80 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
81 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
82 if (!LII) return RII ? -1 : 0;
83 if (!RII) return 1;
84
85 return LII->getName().compare(RII->getName());
86 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +000087
Douglas Gregord6b5f132009-11-04 22:24:30 +000088 case DeclarationName::ObjCZeroArgSelector:
89 case DeclarationName::ObjCOneArgSelector:
90 case DeclarationName::ObjCMultiArgSelector: {
91 Selector LHSSelector = LHS.getObjCSelector();
92 Selector RHSSelector = RHS.getObjCSelector();
John McCall7fe0b9e2010-02-13 01:04:05 +000093 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
94 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000095 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
96 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
Douglas Gregord6b5f132009-11-04 22:24:30 +000097
98 switch (LHSId->getName().compare(RHSId->getName())) {
99 case -1: return true;
100 case 1: return false;
101 default: break;
102 }
103 }
John McCall7fe0b9e2010-02-13 01:04:05 +0000104
105 return compareInt(LN, RN);
Douglas Gregord6b5f132009-11-04 22:24:30 +0000106 }
107
108 case DeclarationName::CXXConstructorName:
109 case DeclarationName::CXXDestructorName:
110 case DeclarationName::CXXConversionFunctionName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000111 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
112 return -1;
113 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
114 return 1;
115 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000116
117 case DeclarationName::CXXOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000118 return compareInt(LHS.getCXXOverloadedOperator(),
119 RHS.getCXXOverloadedOperator());
Sean Hunt3e518bd2009-11-29 07:34:05 +0000120
121 case DeclarationName::CXXLiteralOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000122 return LHS.getCXXLiteralIdentifier()->getName().compare(
123 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregord6b5f132009-11-04 22:24:30 +0000124
125 case DeclarationName::CXXUsingDirective:
John McCall7fe0b9e2010-02-13 01:04:05 +0000126 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000127 }
128
John McCall7fe0b9e2010-02-13 01:04:05 +0000129 return 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000130}
131
132} // end namespace clang
133
134DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000135 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000136 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000137 return;
138 }
139
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000140 switch (Sel.getNumArgs()) {
141 case 0:
142 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000143 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000144 Ptr |= StoredObjCZeroArgSelector;
145 break;
146
147 case 1:
148 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000149 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000150 Ptr |= StoredObjCOneArgSelector;
151 break;
152
153 default:
154 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000155 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000156 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000157 break;
158 }
159}
160
161DeclarationName::NameKind DeclarationName::getNameKind() const {
162 switch (getStoredNameKind()) {
163 case StoredIdentifier: return Identifier;
164 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
165 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
166
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000167 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000168 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000169 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000170 return CXXConstructorName;
171
Mike Stump1eb44332009-09-09 15:08:12 +0000172 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000173 return CXXDestructorName;
174
Mike Stump1eb44332009-09-09 15:08:12 +0000175 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000176 return CXXConversionFunctionName;
177
Sean Hunt3e518bd2009-11-29 07:34:05 +0000178 case DeclarationNameExtra::CXXLiteralOperator:
179 return CXXLiteralOperatorName;
180
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000181 case DeclarationNameExtra::CXXUsingDirective:
182 return CXXUsingDirective;
183
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000184 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000185 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000186 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000187 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000188 return CXXOperatorName;
189
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000190 return ObjCMultiArgSelector;
191 }
192 break;
193 }
194
195 // Can't actually get here.
Chris Lattnerac8d75f2009-03-21 06:40:50 +0000196 assert(0 && "This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000197 return Identifier;
198}
199
Douglas Gregor48026d22010-01-11 18:40:55 +0000200bool DeclarationName::isDependentName() const {
201 QualType T = getCXXNameType();
202 return !T.isNull() && T->isDependentType();
203}
204
Douglas Gregor10bd3682008-11-17 22:58:34 +0000205std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000206 std::string Result;
207 llvm::raw_string_ostream OS(Result);
208 printName(OS);
209 return OS.str();
210}
211
212void DeclarationName::printName(llvm::raw_ostream &OS) const {
Douglas Gregor10bd3682008-11-17 22:58:34 +0000213 switch (getNameKind()) {
214 case Identifier:
215 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000216 OS << II->getName();
217 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000218
219 case ObjCZeroArgSelector:
220 case ObjCOneArgSelector:
221 case ObjCMultiArgSelector:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000222 OS << getObjCSelector().getAsString();
223 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000224
225 case CXXConstructorName: {
226 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000227 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000228 OS << ClassRec->getDecl();
229 else
230 OS << ClassType.getAsString();
231 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000232 }
233
234 case CXXDestructorName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000235 OS << '~';
Douglas Gregor10bd3682008-11-17 22:58:34 +0000236 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000237 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000238 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000239 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000240 OS << Type.getAsString();
241 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000242 }
243
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000244 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000245 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000246 0,
247#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
248 Spelling,
249#include "clang/Basic/OperatorKinds.def"
250 };
251 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
252 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000253
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000254 OS << "operator";
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000255 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000256 OS << ' ';
257 OS << OpName;
258 return;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000259 }
260
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000261 case CXXLiteralOperatorName:
262 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
263 return;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000264
Douglas Gregor10bd3682008-11-17 22:58:34 +0000265 case CXXConversionFunctionName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000266 OS << "operator ";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000267 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000268 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000269 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000270 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000271 OS << Type.getAsString();
272 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000273 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000274 case CXXUsingDirective:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000275 OS << "<using-directive>";
276 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000277 }
278
279 assert(false && "Unexpected declaration name kind");
Douglas Gregor10bd3682008-11-17 22:58:34 +0000280}
281
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000282QualType DeclarationName::getCXXNameType() const {
283 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
284 return CXXName->Type;
285 else
286 return QualType();
287}
288
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000289OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
290 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000291 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000292 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
293 return static_cast<OverloadedOperatorKind>(value);
294 } else {
295 return OO_None;
296 }
297}
298
Sean Hunt3e518bd2009-11-29 07:34:05 +0000299IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
300 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
301 return CXXLit->ID;
302 else
303 return 0;
304}
305
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000306Selector DeclarationName::getObjCSelector() const {
307 switch (getNameKind()) {
308 case ObjCZeroArgSelector:
309 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
310
311 case ObjCOneArgSelector:
312 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
313
314 case ObjCMultiArgSelector:
315 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
316
317 default:
318 break;
319 }
320
321 return Selector();
322}
323
Douglas Gregor2def4832008-11-17 20:34:05 +0000324void *DeclarationName::getFETokenInfoAsVoid() const {
325 switch (getNameKind()) {
326 case Identifier:
327 return getAsIdentifierInfo()->getFETokenInfo<void>();
328
329 case CXXConstructorName:
330 case CXXDestructorName:
331 case CXXConversionFunctionName:
332 return getAsCXXSpecialName()->FETokenInfo;
333
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000334 case CXXOperatorName:
335 return getAsCXXOperatorIdName()->FETokenInfo;
336
Sean Hunt3e518bd2009-11-29 07:34:05 +0000337 case CXXLiteralOperatorName:
338 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
339
Douglas Gregor2def4832008-11-17 20:34:05 +0000340 default:
341 assert(false && "Declaration name has no FETokenInfo");
342 }
343 return 0;
344}
345
346void DeclarationName::setFETokenInfo(void *T) {
347 switch (getNameKind()) {
348 case Identifier:
349 getAsIdentifierInfo()->setFETokenInfo(T);
350 break;
351
352 case CXXConstructorName:
353 case CXXDestructorName:
354 case CXXConversionFunctionName:
355 getAsCXXSpecialName()->FETokenInfo = T;
356 break;
357
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000358 case CXXOperatorName:
359 getAsCXXOperatorIdName()->FETokenInfo = T;
360 break;
361
Sean Hunt3e518bd2009-11-29 07:34:05 +0000362 case CXXLiteralOperatorName:
363 getCXXLiteralIdentifier()->setFETokenInfo(T);
364 break;
365
Douglas Gregor2def4832008-11-17 20:34:05 +0000366 default:
367 assert(false && "Declaration name has no FETokenInfo");
368 }
369}
370
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000371DeclarationName DeclarationName::getUsingDirectiveName() {
372 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000373 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000374 { DeclarationNameExtra::CXXUsingDirective };
375
376 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
377 Ptr |= StoredDeclarationNameExtra;
378
379 return DeclarationName(Ptr);
380}
381
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000382void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000383 printName(llvm::errs());
384 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000385}
386
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000387DeclarationNameTable::DeclarationNameTable(ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000388 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000389 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000390
391 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000392 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000393 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000394 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000395 = Op + DeclarationNameExtra::CXXConversionFunction;
396 CXXOperatorNames[Op].FETokenInfo = 0;
397 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000398}
399
400DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000401 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000402 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000403 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
404 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000405 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000406
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000407 if (Ctx.FreeMemory) {
408 llvm::FoldingSetIterator<CXXSpecialName>
409 SI = SpecialNames->begin(), SE = SpecialNames->end();
410
411 while (SI != SE) {
412 CXXSpecialName *n = &*SI++;
413 Ctx.Deallocate(n);
414 }
415
416 llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
417 LI = LiteralNames->begin(), LE = LiteralNames->end();
418
419 while (LI != LE) {
420 CXXLiteralOperatorIdName *n = &*LI++;
421 Ctx.Deallocate(n);
422 }
423
424 Ctx.Deallocate(CXXOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000425 }
426
427 delete SpecialNames;
428 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000429}
430
Mike Stump1eb44332009-09-09 15:08:12 +0000431DeclarationName
432DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000433 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000434 assert(Kind >= DeclarationName::CXXConstructorName &&
435 Kind <= DeclarationName::CXXConversionFunctionName &&
436 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000437 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000438 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
439
440 DeclarationNameExtra::ExtraKind EKind;
441 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000442 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000443 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000444 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000445 break;
446 case DeclarationName::CXXDestructorName:
447 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000448 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000449 break;
450 case DeclarationName::CXXConversionFunctionName:
451 EKind = DeclarationNameExtra::CXXConversionFunction;
452 break;
453 default:
454 return DeclarationName();
455 }
456
457 // Unique selector, to guarantee there is one per name.
458 llvm::FoldingSetNodeID ID;
459 ID.AddInteger(EKind);
460 ID.AddPointer(Ty.getAsOpaquePtr());
461
462 void *InsertPos = 0;
463 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
464 return DeclarationName(Name);
465
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000466 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000467 SpecialName->ExtraKindOrNumArgs = EKind;
468 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000469 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000470
471 SpecialNames->InsertNode(SpecialName, InsertPos);
472 return DeclarationName(SpecialName);
473}
474
Mike Stump1eb44332009-09-09 15:08:12 +0000475DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000476DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
477 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
478}
479
Sean Hunt3e518bd2009-11-29 07:34:05 +0000480DeclarationName
481DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000482 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
483 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
484 (CXXLiteralOperatorNames);
485
486 llvm::FoldingSetNodeID ID;
487 ID.AddPointer(II);
488
489 void *InsertPos = 0;
490 if (CXXLiteralOperatorIdName *Name =
491 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
492 return DeclarationName (Name);
493
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000494 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000495 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
496 LiteralName->ID = II;
Sean Hunta6c058d2010-01-13 09:01:02 +0000497
498 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000499 return DeclarationName(LiteralName);
500}
501
Mike Stump1eb44332009-09-09 15:08:12 +0000502unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000503llvm::DenseMapInfo<clang::DeclarationName>::
504getHashValue(clang::DeclarationName N) {
505 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
506}
507