blob: 324a2cbf856ef07fd96a710386cd2087c9983779 [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
Richard Smith3a5032b2012-03-09 08:37:16 +000056/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
Sean Hunt3e518bd2009-11-29 07:34:05 +000057/// 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
Richard Smith3a5032b2012-03-09 08:37:16 +000067 /// FETokenInfo - Extra information associated with this operator
68 /// name that can be used by the front end.
69 void *FETokenInfo;
70
Sean Hunta6c058d2010-01-13 09:01:02 +000071 void Profile(llvm::FoldingSetNodeID &FSID) {
72 FSID.AddPointer(ID);
73 }
Sean Hunt3e518bd2009-11-29 07:34:05 +000074};
75
John McCall7fe0b9e2010-02-13 01:04:05 +000076static int compareInt(unsigned A, unsigned B) {
77 return (A < B ? -1 : (A > B ? 1 : 0));
78}
79
80int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000081 if (LHS.getNameKind() != RHS.getNameKind())
John McCall7fe0b9e2010-02-13 01:04:05 +000082 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregord6b5f132009-11-04 22:24:30 +000083
84 switch (LHS.getNameKind()) {
John McCall7fe0b9e2010-02-13 01:04:05 +000085 case DeclarationName::Identifier: {
86 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88 if (!LII) return RII ? -1 : 0;
89 if (!RII) return 1;
90
91 return LII->getName().compare(RII->getName());
92 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +000093
Douglas Gregord6b5f132009-11-04 22:24:30 +000094 case DeclarationName::ObjCZeroArgSelector:
95 case DeclarationName::ObjCOneArgSelector:
96 case DeclarationName::ObjCMultiArgSelector: {
97 Selector LHSSelector = LHS.getObjCSelector();
98 Selector RHSSelector = RHS.getObjCSelector();
John McCall7fe0b9e2010-02-13 01:04:05 +000099 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregor813d8342011-02-18 22:29:55 +0000101 switch (LHSSelector.getNameForSlot(I).compare(
102 RHSSelector.getNameForSlot(I))) {
Douglas Gregord6b5f132009-11-04 22:24:30 +0000103 case -1: return true;
104 case 1: return false;
105 default: break;
106 }
107 }
John McCall7fe0b9e2010-02-13 01:04:05 +0000108
109 return compareInt(LN, RN);
Douglas Gregord6b5f132009-11-04 22:24:30 +0000110 }
111
112 case DeclarationName::CXXConstructorName:
113 case DeclarationName::CXXDestructorName:
114 case DeclarationName::CXXConversionFunctionName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000115 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116 return -1;
117 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118 return 1;
119 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000120
121 case DeclarationName::CXXOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000122 return compareInt(LHS.getCXXOverloadedOperator(),
123 RHS.getCXXOverloadedOperator());
Sean Hunt3e518bd2009-11-29 07:34:05 +0000124
125 case DeclarationName::CXXLiteralOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000126 return LHS.getCXXLiteralIdentifier()->getName().compare(
127 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregord6b5f132009-11-04 22:24:30 +0000128
129 case DeclarationName::CXXUsingDirective:
John McCall7fe0b9e2010-02-13 01:04:05 +0000130 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000131 }
David Blaikie30263482012-01-20 21:50:17 +0000132
133 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000134}
135
136} // end namespace clang
137
138DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000139 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000140 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000141 return;
142 }
143
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000144 switch (Sel.getNumArgs()) {
145 case 0:
146 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000147 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000148 Ptr |= StoredObjCZeroArgSelector;
149 break;
150
151 case 1:
152 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000153 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000154 Ptr |= StoredObjCOneArgSelector;
155 break;
156
157 default:
158 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000159 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000160 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000161 break;
162 }
163}
164
165DeclarationName::NameKind DeclarationName::getNameKind() const {
166 switch (getStoredNameKind()) {
167 case StoredIdentifier: return Identifier;
168 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
169 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
170
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000171 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000172 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000173 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000174 return CXXConstructorName;
175
Mike Stump1eb44332009-09-09 15:08:12 +0000176 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000177 return CXXDestructorName;
178
Mike Stump1eb44332009-09-09 15:08:12 +0000179 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000180 return CXXConversionFunctionName;
181
Sean Hunt3e518bd2009-11-29 07:34:05 +0000182 case DeclarationNameExtra::CXXLiteralOperator:
183 return CXXLiteralOperatorName;
184
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000185 case DeclarationNameExtra::CXXUsingDirective:
186 return CXXUsingDirective;
187
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000188 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000189 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000190 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000191 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000192 return CXXOperatorName;
193
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000194 return ObjCMultiArgSelector;
195 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000196 }
197
198 // Can't actually get here.
David Blaikieb219cfc2011-09-23 05:06:16 +0000199 llvm_unreachable("This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000200}
201
Douglas Gregor48026d22010-01-11 18:40:55 +0000202bool DeclarationName::isDependentName() const {
203 QualType T = getCXXNameType();
204 return !T.isNull() && T->isDependentType();
205}
206
Douglas Gregor10bd3682008-11-17 22:58:34 +0000207std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000208 std::string Result;
209 llvm::raw_string_ostream OS(Result);
210 printName(OS);
211 return OS.str();
212}
213
Chris Lattner5f9e2722011-07-23 10:55:15 +0000214void DeclarationName::printName(raw_ostream &OS) const {
Douglas Gregor10bd3682008-11-17 22:58:34 +0000215 switch (getNameKind()) {
216 case Identifier:
217 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000218 OS << II->getName();
219 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000220
221 case ObjCZeroArgSelector:
222 case ObjCOneArgSelector:
223 case ObjCMultiArgSelector:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000224 OS << getObjCSelector().getAsString();
225 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000226
227 case CXXConstructorName: {
228 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000229 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000230 OS << *ClassRec->getDecl();
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000231 else
232 OS << ClassType.getAsString();
233 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000234 }
235
236 case CXXDestructorName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000237 OS << '~';
Douglas Gregor10bd3682008-11-17 22:58:34 +0000238 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000239 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000240 OS << *Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000241 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000242 OS << Type.getAsString();
243 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000244 }
245
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000246 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000247 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000248 0,
249#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
250 Spelling,
251#include "clang/Basic/OperatorKinds.def"
252 };
253 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
254 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000255
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000256 OS << "operator";
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000257 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000258 OS << ' ';
259 OS << OpName;
260 return;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000261 }
262
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000263 case CXXLiteralOperatorName:
264 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
265 return;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000266
Douglas Gregor10bd3682008-11-17 22:58:34 +0000267 case CXXConversionFunctionName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000268 OS << "operator ";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000269 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000270 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000271 OS << *Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000272 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000273 OS << Type.getAsString();
274 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000275 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000276 case CXXUsingDirective:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000277 OS << "<using-directive>";
278 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000279 }
280
David Blaikieb219cfc2011-09-23 05:06:16 +0000281 llvm_unreachable("Unexpected declaration name kind");
Douglas Gregor10bd3682008-11-17 22:58:34 +0000282}
283
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000284QualType DeclarationName::getCXXNameType() const {
285 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
286 return CXXName->Type;
287 else
288 return QualType();
289}
290
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000291OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
292 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000293 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000294 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
295 return static_cast<OverloadedOperatorKind>(value);
296 } else {
297 return OO_None;
298 }
299}
300
Sean Hunt3e518bd2009-11-29 07:34:05 +0000301IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
302 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
303 return CXXLit->ID;
304 else
305 return 0;
306}
307
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000308Selector DeclarationName::getObjCSelector() const {
309 switch (getNameKind()) {
310 case ObjCZeroArgSelector:
311 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
312
313 case ObjCOneArgSelector:
314 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
315
316 case ObjCMultiArgSelector:
317 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
318
319 default:
320 break;
321 }
322
323 return Selector();
324}
325
Douglas Gregor514d3b62012-05-03 23:18:44 +0000326void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregor2def4832008-11-17 20:34:05 +0000327 switch (getNameKind()) {
328 case Identifier:
Douglas Gregor514d3b62012-05-03 23:18:44 +0000329 llvm_unreachable("Handled by getFETokenInfoAsVoid()");
Douglas Gregor2def4832008-11-17 20:34:05 +0000330
331 case CXXConstructorName:
332 case CXXDestructorName:
333 case CXXConversionFunctionName:
334 return getAsCXXSpecialName()->FETokenInfo;
335
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000336 case CXXOperatorName:
337 return getAsCXXOperatorIdName()->FETokenInfo;
338
Sean Hunt3e518bd2009-11-29 07:34:05 +0000339 case CXXLiteralOperatorName:
Richard Smith3a5032b2012-03-09 08:37:16 +0000340 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000341
Douglas Gregor2def4832008-11-17 20:34:05 +0000342 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000343 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000344 }
Douglas Gregor2def4832008-11-17 20:34:05 +0000345}
346
347void DeclarationName::setFETokenInfo(void *T) {
348 switch (getNameKind()) {
349 case Identifier:
350 getAsIdentifierInfo()->setFETokenInfo(T);
351 break;
352
353 case CXXConstructorName:
354 case CXXDestructorName:
355 case CXXConversionFunctionName:
356 getAsCXXSpecialName()->FETokenInfo = T;
357 break;
358
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000359 case CXXOperatorName:
360 getAsCXXOperatorIdName()->FETokenInfo = T;
361 break;
362
Sean Hunt3e518bd2009-11-29 07:34:05 +0000363 case CXXLiteralOperatorName:
Richard Smith3a5032b2012-03-09 08:37:16 +0000364 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000365 break;
366
Douglas Gregor2def4832008-11-17 20:34:05 +0000367 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000368 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000369 }
370}
371
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000372DeclarationName DeclarationName::getUsingDirectiveName() {
373 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000374 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000375 { DeclarationNameExtra::CXXUsingDirective };
376
377 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
378 Ptr |= StoredDeclarationNameExtra;
379
380 return DeclarationName(Ptr);
381}
382
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000383void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000384 printName(llvm::errs());
385 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000386}
387
Jay Foad4ba2a172011-01-12 09:06:06 +0000388DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000389 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000390 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000391
392 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000393 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000394 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000395 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000396 = Op + DeclarationNameExtra::CXXConversionFunction;
397 CXXOperatorNames[Op].FETokenInfo = 0;
398 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000399}
400
401DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000402 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000403 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000404 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
405 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000406 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000407
Sean Hunta6c058d2010-01-13 09:01:02 +0000408 delete SpecialNames;
409 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000410}
411
Mike Stump1eb44332009-09-09 15:08:12 +0000412DeclarationName
413DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000414 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000415 assert(Kind >= DeclarationName::CXXConstructorName &&
416 Kind <= DeclarationName::CXXConversionFunctionName &&
417 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000418 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000419 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
420
421 DeclarationNameExtra::ExtraKind EKind;
422 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000423 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000424 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000425 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000426 break;
427 case DeclarationName::CXXDestructorName:
428 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000429 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000430 break;
431 case DeclarationName::CXXConversionFunctionName:
432 EKind = DeclarationNameExtra::CXXConversionFunction;
433 break;
434 default:
435 return DeclarationName();
436 }
437
438 // Unique selector, to guarantee there is one per name.
439 llvm::FoldingSetNodeID ID;
440 ID.AddInteger(EKind);
441 ID.AddPointer(Ty.getAsOpaquePtr());
442
443 void *InsertPos = 0;
444 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
445 return DeclarationName(Name);
446
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000447 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000448 SpecialName->ExtraKindOrNumArgs = EKind;
449 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000450 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000451
452 SpecialNames->InsertNode(SpecialName, InsertPos);
453 return DeclarationName(SpecialName);
454}
455
Mike Stump1eb44332009-09-09 15:08:12 +0000456DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000457DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
458 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
459}
460
Sean Hunt3e518bd2009-11-29 07:34:05 +0000461DeclarationName
462DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000463 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
464 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
465 (CXXLiteralOperatorNames);
466
467 llvm::FoldingSetNodeID ID;
468 ID.AddPointer(II);
469
470 void *InsertPos = 0;
471 if (CXXLiteralOperatorIdName *Name =
472 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
473 return DeclarationName (Name);
474
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000475 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000476 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
477 LiteralName->ID = II;
Richard Smith3a5032b2012-03-09 08:37:16 +0000478 LiteralName->FETokenInfo = 0;
Sean Hunta6c058d2010-01-13 09:01:02 +0000479
480 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000481 return DeclarationName(LiteralName);
482}
483
Mike Stump1eb44332009-09-09 15:08:12 +0000484unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000485llvm::DenseMapInfo<clang::DeclarationName>::
486getHashValue(clang::DeclarationName N) {
487 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
488}
489
Abramo Bagnara25777432010-08-11 22:01:17 +0000490DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
491 switch (Name.getNameKind()) {
492 case DeclarationName::Identifier:
493 break;
494 case DeclarationName::CXXConstructorName:
495 case DeclarationName::CXXDestructorName:
496 case DeclarationName::CXXConversionFunctionName:
497 NamedType.TInfo = 0;
498 break;
499 case DeclarationName::CXXOperatorName:
500 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
501 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
502 break;
503 case DeclarationName::CXXLiteralOperatorName:
504 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
505 break;
506 case DeclarationName::ObjCZeroArgSelector:
507 case DeclarationName::ObjCOneArgSelector:
508 case DeclarationName::ObjCMultiArgSelector:
509 // FIXME: ?
510 break;
511 case DeclarationName::CXXUsingDirective:
512 break;
513 }
514}
515
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000516bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
517 switch (Name.getNameKind()) {
518 case DeclarationName::Identifier:
519 case DeclarationName::ObjCZeroArgSelector:
520 case DeclarationName::ObjCOneArgSelector:
521 case DeclarationName::ObjCMultiArgSelector:
522 case DeclarationName::CXXOperatorName:
523 case DeclarationName::CXXLiteralOperatorName:
524 case DeclarationName::CXXUsingDirective:
525 return false;
526
527 case DeclarationName::CXXConstructorName:
528 case DeclarationName::CXXDestructorName:
529 case DeclarationName::CXXConversionFunctionName:
530 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
531 return TInfo->getType()->containsUnexpandedParameterPack();
532
533 return Name.getCXXNameType()->containsUnexpandedParameterPack();
534 }
Chandler Carruthf24e54a2010-12-15 07:29:18 +0000535 llvm_unreachable("All name kinds handled.");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000536}
537
Douglas Gregor561f8122011-07-01 01:22:09 +0000538bool DeclarationNameInfo::isInstantiationDependent() const {
539 switch (Name.getNameKind()) {
540 case DeclarationName::Identifier:
541 case DeclarationName::ObjCZeroArgSelector:
542 case DeclarationName::ObjCOneArgSelector:
543 case DeclarationName::ObjCMultiArgSelector:
544 case DeclarationName::CXXOperatorName:
545 case DeclarationName::CXXLiteralOperatorName:
546 case DeclarationName::CXXUsingDirective:
547 return false;
548
549 case DeclarationName::CXXConstructorName:
550 case DeclarationName::CXXDestructorName:
551 case DeclarationName::CXXConversionFunctionName:
552 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
553 return TInfo->getType()->isInstantiationDependentType();
554
555 return Name.getCXXNameType()->isInstantiationDependentType();
556 }
557 llvm_unreachable("All name kinds handled.");
558}
559
Abramo Bagnara25777432010-08-11 22:01:17 +0000560std::string DeclarationNameInfo::getAsString() const {
561 std::string Result;
562 llvm::raw_string_ostream OS(Result);
563 printName(OS);
564 return OS.str();
565}
566
Chris Lattner5f9e2722011-07-23 10:55:15 +0000567void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnara25777432010-08-11 22:01:17 +0000568 switch (Name.getNameKind()) {
569 case DeclarationName::Identifier:
570 case DeclarationName::ObjCZeroArgSelector:
571 case DeclarationName::ObjCOneArgSelector:
572 case DeclarationName::ObjCMultiArgSelector:
573 case DeclarationName::CXXOperatorName:
574 case DeclarationName::CXXLiteralOperatorName:
575 case DeclarationName::CXXUsingDirective:
576 Name.printName(OS);
577 return;
578
579 case DeclarationName::CXXConstructorName:
580 case DeclarationName::CXXDestructorName:
581 case DeclarationName::CXXConversionFunctionName:
582 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
583 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
584 OS << '~';
585 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
586 OS << "operator ";
587 OS << TInfo->getType().getAsString();
588 }
589 else
590 Name.printName(OS);
591 return;
592 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000593 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000594}
595
596SourceLocation DeclarationNameInfo::getEndLoc() const {
597 switch (Name.getNameKind()) {
598 case DeclarationName::Identifier:
599 return NameLoc;
600
601 case DeclarationName::CXXOperatorName: {
602 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
603 return SourceLocation::getFromRawEncoding(raw);
604 }
605
606 case DeclarationName::CXXLiteralOperatorName: {
607 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
608 return SourceLocation::getFromRawEncoding(raw);
609 }
610
611 case DeclarationName::CXXConstructorName:
612 case DeclarationName::CXXDestructorName:
613 case DeclarationName::CXXConversionFunctionName:
614 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
615 return TInfo->getTypeLoc().getEndLoc();
616 else
617 return NameLoc;
618
619 // DNInfo work in progress: FIXME.
620 case DeclarationName::ObjCZeroArgSelector:
621 case DeclarationName::ObjCOneArgSelector:
622 case DeclarationName::ObjCMultiArgSelector:
623 case DeclarationName::CXXUsingDirective:
624 return NameLoc;
625 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000626 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000627}