blob: bf647ed7ac3557533afeb2688f9a81e7a81cc84d [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"
Abramo Bagnara25777432010-08-11 22:01:17 +000018#include "clang/AST/TypeLoc.h"
Douglas Gregord6b5f132009-11-04 22:24:30 +000019#include "clang/AST/TypeOrdering.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000020#include "clang/Basic/IdentifierTable.h"
Douglas Gregor370187c2009-04-22 21:45:53 +000021#include "llvm/ADT/DenseMap.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000022#include "llvm/ADT/FoldingSet.h"
Chandler Carruthf24e54a2010-12-15 07:29:18 +000023#include "llvm/Support/ErrorHandling.h"
Benjamin Kramerf6cde772010-04-17 09:56:45 +000024#include "llvm/Support/raw_ostream.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000025using namespace clang;
26
27namespace clang {
28/// CXXSpecialName - Records the type associated with one of the
29/// "special" kinds of declaration names in C++, e.g., constructors,
30/// destructors, and conversion functions.
Mike Stump1eb44332009-09-09 15:08:12 +000031class CXXSpecialName
Douglas Gregor2e1cd422008-11-17 14:58:09 +000032 : public DeclarationNameExtra, public llvm::FoldingSetNode {
33public:
Douglas Gregor2def4832008-11-17 20:34:05 +000034 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000035 QualType Type;
36
Douglas Gregor2def4832008-11-17 20:34:05 +000037 /// FETokenInfo - Extra information associated with this declaration
38 /// name that can be used by the front end.
39 void *FETokenInfo;
40
Douglas Gregor2e1cd422008-11-17 14:58:09 +000041 void Profile(llvm::FoldingSetNodeID &ID) {
42 ID.AddInteger(ExtraKindOrNumArgs);
43 ID.AddPointer(Type.getAsOpaquePtr());
44 }
45};
46
Douglas Gregore94ca9e42008-11-18 14:39:36 +000047/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump1eb44332009-09-09 15:08:12 +000048/// overloaded operator in C++, such as "operator+.
Douglas Gregore94ca9e42008-11-18 14:39:36 +000049class CXXOperatorIdName : public DeclarationNameExtra {
50public:
51 /// FETokenInfo - Extra information associated with this operator
52 /// name that can be used by the front end.
53 void *FETokenInfo;
54};
55
Sean Hunt3e518bd2009-11-29 07:34:05 +000056/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
57/// name.
58///
59/// This identifier is stored here rather than directly in DeclarationName so as
60/// to allow Objective-C selectors, which are about a million times more common,
61/// to consume minimal memory.
Sean Hunta6c058d2010-01-13 09:01:02 +000062class CXXLiteralOperatorIdName
63 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Sean Hunt3e518bd2009-11-29 07:34:05 +000064public:
65 IdentifierInfo *ID;
Sean Hunta6c058d2010-01-13 09:01:02 +000066
67 void Profile(llvm::FoldingSetNodeID &FSID) {
68 FSID.AddPointer(ID);
69 }
Sean Hunt3e518bd2009-11-29 07:34:05 +000070};
71
John McCall7fe0b9e2010-02-13 01:04:05 +000072static int compareInt(unsigned A, unsigned B) {
73 return (A < B ? -1 : (A > B ? 1 : 0));
74}
75
76int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000077 if (LHS.getNameKind() != RHS.getNameKind())
John McCall7fe0b9e2010-02-13 01:04:05 +000078 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregord6b5f132009-11-04 22:24:30 +000079
80 switch (LHS.getNameKind()) {
John McCall7fe0b9e2010-02-13 01:04:05 +000081 case DeclarationName::Identifier: {
82 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
83 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
84 if (!LII) return RII ? -1 : 0;
85 if (!RII) return 1;
86
87 return LII->getName().compare(RII->getName());
88 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +000089
Douglas Gregord6b5f132009-11-04 22:24:30 +000090 case DeclarationName::ObjCZeroArgSelector:
91 case DeclarationName::ObjCOneArgSelector:
92 case DeclarationName::ObjCMultiArgSelector: {
93 Selector LHSSelector = LHS.getObjCSelector();
94 Selector RHSSelector = RHS.getObjCSelector();
John McCall7fe0b9e2010-02-13 01:04:05 +000095 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
96 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregor813d8342011-02-18 22:29:55 +000097 switch (LHSSelector.getNameForSlot(I).compare(
98 RHSSelector.getNameForSlot(I))) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000099 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.
David Blaikieb219cfc2011-09-23 05:06:16 +0000196 llvm_unreachable("This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000197}
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
Chris Lattner5f9e2722011-07-23 10:55:15 +0000211void DeclarationName::printName(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 Kramerb8989f22011-10-14 18:45:37 +0000227 OS << *ClassRec->getDecl();
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000228 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 Kramerb8989f22011-10-14 18:45:37 +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 Kramerb8989f22011-10-14 18:45:37 +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
David Blaikieb219cfc2011-09-23 05:06:16 +0000278 llvm_unreachable("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:
David Blaikieb219cfc2011-09-23 05:06:16 +0000340 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000341 }
Douglas Gregor2def4832008-11-17 20:34:05 +0000342}
343
344void DeclarationName::setFETokenInfo(void *T) {
345 switch (getNameKind()) {
346 case Identifier:
347 getAsIdentifierInfo()->setFETokenInfo(T);
348 break;
349
350 case CXXConstructorName:
351 case CXXDestructorName:
352 case CXXConversionFunctionName:
353 getAsCXXSpecialName()->FETokenInfo = T;
354 break;
355
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000356 case CXXOperatorName:
357 getAsCXXOperatorIdName()->FETokenInfo = T;
358 break;
359
Sean Hunt3e518bd2009-11-29 07:34:05 +0000360 case CXXLiteralOperatorName:
361 getCXXLiteralIdentifier()->setFETokenInfo(T);
362 break;
363
Douglas Gregor2def4832008-11-17 20:34:05 +0000364 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000365 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000366 }
367}
368
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000369DeclarationName DeclarationName::getUsingDirectiveName() {
370 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000371 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000372 { DeclarationNameExtra::CXXUsingDirective };
373
374 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
375 Ptr |= StoredDeclarationNameExtra;
376
377 return DeclarationName(Ptr);
378}
379
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000380void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000381 printName(llvm::errs());
382 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000383}
384
Jay Foad4ba2a172011-01-12 09:06:06 +0000385DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000386 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000387 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000388
389 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000390 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000391 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000392 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000393 = Op + DeclarationNameExtra::CXXConversionFunction;
394 CXXOperatorNames[Op].FETokenInfo = 0;
395 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000396}
397
398DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000399 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000400 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000401 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
402 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000403 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000404
Sean Hunta6c058d2010-01-13 09:01:02 +0000405 delete SpecialNames;
406 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000407}
408
Mike Stump1eb44332009-09-09 15:08:12 +0000409DeclarationName
410DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000411 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000412 assert(Kind >= DeclarationName::CXXConstructorName &&
413 Kind <= DeclarationName::CXXConversionFunctionName &&
414 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000415 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000416 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
417
418 DeclarationNameExtra::ExtraKind EKind;
419 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000420 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000421 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000422 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000423 break;
424 case DeclarationName::CXXDestructorName:
425 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000426 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000427 break;
428 case DeclarationName::CXXConversionFunctionName:
429 EKind = DeclarationNameExtra::CXXConversionFunction;
430 break;
431 default:
432 return DeclarationName();
433 }
434
435 // Unique selector, to guarantee there is one per name.
436 llvm::FoldingSetNodeID ID;
437 ID.AddInteger(EKind);
438 ID.AddPointer(Ty.getAsOpaquePtr());
439
440 void *InsertPos = 0;
441 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
442 return DeclarationName(Name);
443
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000444 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000445 SpecialName->ExtraKindOrNumArgs = EKind;
446 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000447 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000448
449 SpecialNames->InsertNode(SpecialName, InsertPos);
450 return DeclarationName(SpecialName);
451}
452
Mike Stump1eb44332009-09-09 15:08:12 +0000453DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000454DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
455 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
456}
457
Sean Hunt3e518bd2009-11-29 07:34:05 +0000458DeclarationName
459DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000460 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
461 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
462 (CXXLiteralOperatorNames);
463
464 llvm::FoldingSetNodeID ID;
465 ID.AddPointer(II);
466
467 void *InsertPos = 0;
468 if (CXXLiteralOperatorIdName *Name =
469 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
470 return DeclarationName (Name);
471
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000472 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000473 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
474 LiteralName->ID = II;
Sean Hunta6c058d2010-01-13 09:01:02 +0000475
476 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000477 return DeclarationName(LiteralName);
478}
479
Mike Stump1eb44332009-09-09 15:08:12 +0000480unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000481llvm::DenseMapInfo<clang::DeclarationName>::
482getHashValue(clang::DeclarationName N) {
483 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
484}
485
Abramo Bagnara25777432010-08-11 22:01:17 +0000486DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
487 switch (Name.getNameKind()) {
488 case DeclarationName::Identifier:
489 break;
490 case DeclarationName::CXXConstructorName:
491 case DeclarationName::CXXDestructorName:
492 case DeclarationName::CXXConversionFunctionName:
493 NamedType.TInfo = 0;
494 break;
495 case DeclarationName::CXXOperatorName:
496 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
497 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
498 break;
499 case DeclarationName::CXXLiteralOperatorName:
500 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
501 break;
502 case DeclarationName::ObjCZeroArgSelector:
503 case DeclarationName::ObjCOneArgSelector:
504 case DeclarationName::ObjCMultiArgSelector:
505 // FIXME: ?
506 break;
507 case DeclarationName::CXXUsingDirective:
508 break;
509 }
510}
511
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000512bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
513 switch (Name.getNameKind()) {
514 case DeclarationName::Identifier:
515 case DeclarationName::ObjCZeroArgSelector:
516 case DeclarationName::ObjCOneArgSelector:
517 case DeclarationName::ObjCMultiArgSelector:
518 case DeclarationName::CXXOperatorName:
519 case DeclarationName::CXXLiteralOperatorName:
520 case DeclarationName::CXXUsingDirective:
521 return false;
522
523 case DeclarationName::CXXConstructorName:
524 case DeclarationName::CXXDestructorName:
525 case DeclarationName::CXXConversionFunctionName:
526 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
527 return TInfo->getType()->containsUnexpandedParameterPack();
528
529 return Name.getCXXNameType()->containsUnexpandedParameterPack();
530 }
Chandler Carruthf24e54a2010-12-15 07:29:18 +0000531 llvm_unreachable("All name kinds handled.");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000532}
533
Douglas Gregor561f8122011-07-01 01:22:09 +0000534bool DeclarationNameInfo::isInstantiationDependent() const {
535 switch (Name.getNameKind()) {
536 case DeclarationName::Identifier:
537 case DeclarationName::ObjCZeroArgSelector:
538 case DeclarationName::ObjCOneArgSelector:
539 case DeclarationName::ObjCMultiArgSelector:
540 case DeclarationName::CXXOperatorName:
541 case DeclarationName::CXXLiteralOperatorName:
542 case DeclarationName::CXXUsingDirective:
543 return false;
544
545 case DeclarationName::CXXConstructorName:
546 case DeclarationName::CXXDestructorName:
547 case DeclarationName::CXXConversionFunctionName:
548 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
549 return TInfo->getType()->isInstantiationDependentType();
550
551 return Name.getCXXNameType()->isInstantiationDependentType();
552 }
553 llvm_unreachable("All name kinds handled.");
554}
555
Abramo Bagnara25777432010-08-11 22:01:17 +0000556std::string DeclarationNameInfo::getAsString() const {
557 std::string Result;
558 llvm::raw_string_ostream OS(Result);
559 printName(OS);
560 return OS.str();
561}
562
Chris Lattner5f9e2722011-07-23 10:55:15 +0000563void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnara25777432010-08-11 22:01:17 +0000564 switch (Name.getNameKind()) {
565 case DeclarationName::Identifier:
566 case DeclarationName::ObjCZeroArgSelector:
567 case DeclarationName::ObjCOneArgSelector:
568 case DeclarationName::ObjCMultiArgSelector:
569 case DeclarationName::CXXOperatorName:
570 case DeclarationName::CXXLiteralOperatorName:
571 case DeclarationName::CXXUsingDirective:
572 Name.printName(OS);
573 return;
574
575 case DeclarationName::CXXConstructorName:
576 case DeclarationName::CXXDestructorName:
577 case DeclarationName::CXXConversionFunctionName:
578 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
579 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
580 OS << '~';
581 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
582 OS << "operator ";
583 OS << TInfo->getType().getAsString();
584 }
585 else
586 Name.printName(OS);
587 return;
588 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000589 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000590}
591
592SourceLocation DeclarationNameInfo::getEndLoc() const {
593 switch (Name.getNameKind()) {
594 case DeclarationName::Identifier:
595 return NameLoc;
596
597 case DeclarationName::CXXOperatorName: {
598 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
599 return SourceLocation::getFromRawEncoding(raw);
600 }
601
602 case DeclarationName::CXXLiteralOperatorName: {
603 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
604 return SourceLocation::getFromRawEncoding(raw);
605 }
606
607 case DeclarationName::CXXConstructorName:
608 case DeclarationName::CXXDestructorName:
609 case DeclarationName::CXXConversionFunctionName:
610 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
611 return TInfo->getTypeLoc().getEndLoc();
612 else
613 return NameLoc;
614
615 // DNInfo work in progress: FIXME.
616 case DeclarationName::ObjCZeroArgSelector:
617 case DeclarationName::ObjCOneArgSelector:
618 case DeclarationName::ObjCMultiArgSelector:
619 case DeclarationName::CXXUsingDirective:
620 return NameLoc;
621 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000622 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000623}