blob: 19b58bcbaf03d31c9087b2e28e07e1608c7b4c36 [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"
Chandler Carruth894993f2009-11-15 23:10:57 +000021#include <cstdio>
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 {
205 switch (getNameKind()) {
206 case Identifier:
207 if (const IdentifierInfo *II = getAsIdentifierInfo())
208 return II->getName();
209 return "";
210
211 case ObjCZeroArgSelector:
212 case ObjCOneArgSelector:
213 case ObjCMultiArgSelector:
Chris Lattner077bf5e2008-11-24 03:33:13 +0000214 return getObjCSelector().getAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000215
216 case CXXConstructorName: {
217 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000218 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000219 return ClassRec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000220 return ClassType.getAsString();
221 }
222
223 case CXXDestructorName: {
224 std::string Result = "~";
225 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000226 if (const RecordType *Rec = Type->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000227 Result += Rec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000228 else
229 Result += Type.getAsString();
230 return Result;
231 }
232
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000233 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000234 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000235 0,
236#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
237 Spelling,
238#include "clang/Basic/OperatorKinds.def"
239 };
240 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
241 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000242
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000243 std::string Result = "operator";
244 if (OpName[0] >= 'a' && OpName[0] <= 'z')
245 Result += ' ';
246 Result += OpName;
247 return Result;
248 }
249
Sean Hunt3e518bd2009-11-29 07:34:05 +0000250 case CXXLiteralOperatorName: {
251 return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
252 }
253
Douglas Gregor10bd3682008-11-17 22:58:34 +0000254 case CXXConversionFunctionName: {
255 std::string Result = "operator ";
256 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000257 if (const RecordType *Rec = Type->getAs<RecordType>())
Chris Lattner39f34e92008-11-24 04:00:27 +0000258 Result += Rec->getDecl()->getNameAsString();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000259 else
260 Result += Type.getAsString();
261 return Result;
262 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000263 case CXXUsingDirective:
264 return "<using-directive>";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000265 }
266
267 assert(false && "Unexpected declaration name kind");
268 return "";
269}
270
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000271QualType DeclarationName::getCXXNameType() const {
272 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
273 return CXXName->Type;
274 else
275 return QualType();
276}
277
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000278OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
279 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000280 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000281 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
282 return static_cast<OverloadedOperatorKind>(value);
283 } else {
284 return OO_None;
285 }
286}
287
Sean Hunt3e518bd2009-11-29 07:34:05 +0000288IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
289 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
290 return CXXLit->ID;
291 else
292 return 0;
293}
294
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000295Selector DeclarationName::getObjCSelector() const {
296 switch (getNameKind()) {
297 case ObjCZeroArgSelector:
298 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
299
300 case ObjCOneArgSelector:
301 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
302
303 case ObjCMultiArgSelector:
304 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
305
306 default:
307 break;
308 }
309
310 return Selector();
311}
312
Douglas Gregor2def4832008-11-17 20:34:05 +0000313void *DeclarationName::getFETokenInfoAsVoid() const {
314 switch (getNameKind()) {
315 case Identifier:
316 return getAsIdentifierInfo()->getFETokenInfo<void>();
317
318 case CXXConstructorName:
319 case CXXDestructorName:
320 case CXXConversionFunctionName:
321 return getAsCXXSpecialName()->FETokenInfo;
322
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000323 case CXXOperatorName:
324 return getAsCXXOperatorIdName()->FETokenInfo;
325
Sean Hunt3e518bd2009-11-29 07:34:05 +0000326 case CXXLiteralOperatorName:
327 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
328
Douglas Gregor2def4832008-11-17 20:34:05 +0000329 default:
330 assert(false && "Declaration name has no FETokenInfo");
331 }
332 return 0;
333}
334
335void DeclarationName::setFETokenInfo(void *T) {
336 switch (getNameKind()) {
337 case Identifier:
338 getAsIdentifierInfo()->setFETokenInfo(T);
339 break;
340
341 case CXXConstructorName:
342 case CXXDestructorName:
343 case CXXConversionFunctionName:
344 getAsCXXSpecialName()->FETokenInfo = T;
345 break;
346
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000347 case CXXOperatorName:
348 getAsCXXOperatorIdName()->FETokenInfo = T;
349 break;
350
Sean Hunt3e518bd2009-11-29 07:34:05 +0000351 case CXXLiteralOperatorName:
352 getCXXLiteralIdentifier()->setFETokenInfo(T);
353 break;
354
Douglas Gregor2def4832008-11-17 20:34:05 +0000355 default:
356 assert(false && "Declaration name has no FETokenInfo");
357 }
358}
359
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000360DeclarationName DeclarationName::getUsingDirectiveName() {
361 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000362 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000363 { DeclarationNameExtra::CXXUsingDirective };
364
365 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
366 Ptr |= StoredDeclarationNameExtra;
367
368 return DeclarationName(Ptr);
369}
370
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000371void DeclarationName::dump() const {
372 fprintf(stderr, "%s\n", getAsString().c_str());
373}
374
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000375DeclarationNameTable::DeclarationNameTable() {
376 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000377 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000378
379 // Initialize the overloaded operator names.
380 CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
381 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000382 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000383 = Op + DeclarationNameExtra::CXXConversionFunction;
384 CXXOperatorNames[Op].FETokenInfo = 0;
385 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000386}
387
388DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000389 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000390 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000391 llvm::FoldingSetIterator<CXXSpecialName>
392 SI = SpecialNames->begin(), SE = SpecialNames->end();
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000393
Sean Hunta6c058d2010-01-13 09:01:02 +0000394 while (SI != SE) {
395 CXXSpecialName *n = &*SI++;
Nuno Lopesf9d1e4b2008-12-14 21:53:25 +0000396 delete n;
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000397 }
398
Sean Hunta6c058d2010-01-13 09:01:02 +0000399
400 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
401 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
402 (CXXLiteralOperatorNames);
403 llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
404 LI = LiteralNames->begin(), LE = LiteralNames->end();
405
406 while (LI != LE) {
407 CXXLiteralOperatorIdName *n = &*LI++;
408 delete n;
409 }
410
411 delete SpecialNames;
412 delete LiteralNames;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000413 delete [] CXXOperatorNames;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000414}
415
Mike Stump1eb44332009-09-09 15:08:12 +0000416DeclarationName
417DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000418 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000419 assert(Kind >= DeclarationName::CXXConstructorName &&
420 Kind <= DeclarationName::CXXConversionFunctionName &&
421 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000422 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000423 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
424
425 DeclarationNameExtra::ExtraKind EKind;
426 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000427 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000428 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000429 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000430 break;
431 case DeclarationName::CXXDestructorName:
432 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000433 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000434 break;
435 case DeclarationName::CXXConversionFunctionName:
436 EKind = DeclarationNameExtra::CXXConversionFunction;
437 break;
438 default:
439 return DeclarationName();
440 }
441
442 // Unique selector, to guarantee there is one per name.
443 llvm::FoldingSetNodeID ID;
444 ID.AddInteger(EKind);
445 ID.AddPointer(Ty.getAsOpaquePtr());
446
447 void *InsertPos = 0;
448 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
449 return DeclarationName(Name);
450
451 CXXSpecialName *SpecialName = new CXXSpecialName;
452 SpecialName->ExtraKindOrNumArgs = EKind;
453 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000454 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000455
456 SpecialNames->InsertNode(SpecialName, InsertPos);
457 return DeclarationName(SpecialName);
458}
459
Mike Stump1eb44332009-09-09 15:08:12 +0000460DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000461DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
462 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
463}
464
Sean Hunt3e518bd2009-11-29 07:34:05 +0000465DeclarationName
466DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000467 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
468 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
469 (CXXLiteralOperatorNames);
470
471 llvm::FoldingSetNodeID ID;
472 ID.AddPointer(II);
473
474 void *InsertPos = 0;
475 if (CXXLiteralOperatorIdName *Name =
476 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
477 return DeclarationName (Name);
478
Sean Hunt3e518bd2009-11-29 07:34:05 +0000479 CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
480 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
481 LiteralName->ID = II;
Sean Hunta6c058d2010-01-13 09:01:02 +0000482
483 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000484 return DeclarationName(LiteralName);
485}
486
Mike Stump1eb44332009-09-09 15:08:12 +0000487unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000488llvm::DenseMapInfo<clang::DeclarationName>::
489getHashValue(clang::DeclarationName N) {
490 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
491}
492