blob: e064e23a0ae9a179929bfbf08f6a0209477ccff5 [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
David Blaikie17828ca2013-05-14 21:04:00 +0000136raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137 switch (N.getNameKind()) {
138 case DeclarationName::Identifier:
139 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140 OS << II->getName();
141 return OS;
142
143 case DeclarationName::ObjCZeroArgSelector:
144 case DeclarationName::ObjCOneArgSelector:
145 case DeclarationName::ObjCMultiArgSelector:
146 return OS << N.getObjCSelector().getAsString();
147
148 case DeclarationName::CXXConstructorName: {
149 QualType ClassType = N.getCXXNameType();
150 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
151 return OS << *ClassRec->getDecl();
152 return OS << ClassType.getAsString();
153 }
154
155 case DeclarationName::CXXDestructorName: {
156 OS << '~';
157 QualType Type = N.getCXXNameType();
158 if (const RecordType *Rec = Type->getAs<RecordType>())
159 return OS << *Rec->getDecl();
160 return OS << Type.getAsString();
161 }
162
163 case DeclarationName::CXXOperatorName: {
164 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165 0,
166#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
167 Spelling,
168#include "clang/Basic/OperatorKinds.def"
169 };
170 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
171 assert(OpName && "not an overloaded operator");
172
173 OS << "operator";
174 if (OpName[0] >= 'a' && OpName[0] <= 'z')
175 OS << ' ';
176 return OS << OpName;
177 }
178
179 case DeclarationName::CXXLiteralOperatorName:
180 return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
181
182 case DeclarationName::CXXConversionFunctionName: {
183 OS << "operator ";
184 QualType Type = N.getCXXNameType();
185 if (const RecordType *Rec = Type->getAs<RecordType>())
186 return OS << *Rec->getDecl();
187 return OS << Type.getAsString();
188 }
189 case DeclarationName::CXXUsingDirective:
190 return OS << "<using-directive>";
191 }
192
193 llvm_unreachable("Unexpected declaration name kind");
194}
195
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000196} // end namespace clang
197
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000198DeclarationName::NameKind DeclarationName::getNameKind() const {
199 switch (getStoredNameKind()) {
200 case StoredIdentifier: return Identifier;
201 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
202 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
203
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000204 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000205 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000206 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000207 return CXXConstructorName;
208
Mike Stump1eb44332009-09-09 15:08:12 +0000209 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000210 return CXXDestructorName;
211
Mike Stump1eb44332009-09-09 15:08:12 +0000212 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000213 return CXXConversionFunctionName;
214
Sean Hunt3e518bd2009-11-29 07:34:05 +0000215 case DeclarationNameExtra::CXXLiteralOperator:
216 return CXXLiteralOperatorName;
217
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000218 case DeclarationNameExtra::CXXUsingDirective:
219 return CXXUsingDirective;
220
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000221 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000222 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000223 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000224 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000225 return CXXOperatorName;
226
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000227 return ObjCMultiArgSelector;
228 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000229 }
230
231 // Can't actually get here.
David Blaikieb219cfc2011-09-23 05:06:16 +0000232 llvm_unreachable("This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000233}
234
Douglas Gregor48026d22010-01-11 18:40:55 +0000235bool DeclarationName::isDependentName() const {
236 QualType T = getCXXNameType();
237 return !T.isNull() && T->isDependentType();
238}
239
Douglas Gregor10bd3682008-11-17 22:58:34 +0000240std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000241 std::string Result;
242 llvm::raw_string_ostream OS(Result);
David Blaikie17828ca2013-05-14 21:04:00 +0000243 OS << *this;
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000244 return OS.str();
245}
246
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000247QualType DeclarationName::getCXXNameType() const {
248 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
249 return CXXName->Type;
250 else
251 return QualType();
252}
253
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000254OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
255 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000256 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000257 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
258 return static_cast<OverloadedOperatorKind>(value);
259 } else {
260 return OO_None;
261 }
262}
263
Sean Hunt3e518bd2009-11-29 07:34:05 +0000264IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
265 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
266 return CXXLit->ID;
267 else
268 return 0;
269}
270
Douglas Gregor514d3b62012-05-03 23:18:44 +0000271void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregor2def4832008-11-17 20:34:05 +0000272 switch (getNameKind()) {
273 case Identifier:
Benjamin Kramerc4704422012-05-19 16:03:58 +0000274 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregor2def4832008-11-17 20:34:05 +0000275
276 case CXXConstructorName:
277 case CXXDestructorName:
278 case CXXConversionFunctionName:
279 return getAsCXXSpecialName()->FETokenInfo;
280
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000281 case CXXOperatorName:
282 return getAsCXXOperatorIdName()->FETokenInfo;
283
Sean Hunt3e518bd2009-11-29 07:34:05 +0000284 case CXXLiteralOperatorName:
Richard Smith3a5032b2012-03-09 08:37:16 +0000285 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000286
Douglas Gregor2def4832008-11-17 20:34:05 +0000287 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000288 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000289 }
Douglas Gregor2def4832008-11-17 20:34:05 +0000290}
291
292void DeclarationName::setFETokenInfo(void *T) {
293 switch (getNameKind()) {
294 case Identifier:
295 getAsIdentifierInfo()->setFETokenInfo(T);
296 break;
297
298 case CXXConstructorName:
299 case CXXDestructorName:
300 case CXXConversionFunctionName:
301 getAsCXXSpecialName()->FETokenInfo = T;
302 break;
303
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000304 case CXXOperatorName:
305 getAsCXXOperatorIdName()->FETokenInfo = T;
306 break;
307
Sean Hunt3e518bd2009-11-29 07:34:05 +0000308 case CXXLiteralOperatorName:
Richard Smith3a5032b2012-03-09 08:37:16 +0000309 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000310 break;
311
Douglas Gregor2def4832008-11-17 20:34:05 +0000312 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000313 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000314 }
315}
316
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000317DeclarationName DeclarationName::getUsingDirectiveName() {
318 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000319 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000320 { DeclarationNameExtra::CXXUsingDirective };
321
322 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
323 Ptr |= StoredDeclarationNameExtra;
324
325 return DeclarationName(Ptr);
326}
327
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000328void DeclarationName::dump() const {
David Blaikie17828ca2013-05-14 21:04:00 +0000329 llvm::errs() << *this << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000330}
331
Jay Foad4ba2a172011-01-12 09:06:06 +0000332DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000333 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000334 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000335
336 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000337 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000338 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000339 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000340 = Op + DeclarationNameExtra::CXXConversionFunction;
341 CXXOperatorNames[Op].FETokenInfo = 0;
342 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000343}
344
345DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000346 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000347 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000348 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
349 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000350 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000351
Sean Hunta6c058d2010-01-13 09:01:02 +0000352 delete SpecialNames;
353 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000354}
355
Benjamin Kramer9852f582012-12-01 16:35:25 +0000356DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
357 return getCXXSpecialName(DeclarationName::CXXConstructorName,
358 Ty.getUnqualifiedType());
359}
360
361DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
362 return getCXXSpecialName(DeclarationName::CXXDestructorName,
363 Ty.getUnqualifiedType());
364}
365
366DeclarationName
367DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
368 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
369}
370
Mike Stump1eb44332009-09-09 15:08:12 +0000371DeclarationName
372DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000373 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000374 assert(Kind >= DeclarationName::CXXConstructorName &&
375 Kind <= DeclarationName::CXXConversionFunctionName &&
376 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000377 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000378 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
379
380 DeclarationNameExtra::ExtraKind EKind;
381 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000382 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000383 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000384 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000385 break;
386 case DeclarationName::CXXDestructorName:
387 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000388 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000389 break;
390 case DeclarationName::CXXConversionFunctionName:
391 EKind = DeclarationNameExtra::CXXConversionFunction;
392 break;
393 default:
394 return DeclarationName();
395 }
396
397 // Unique selector, to guarantee there is one per name.
398 llvm::FoldingSetNodeID ID;
399 ID.AddInteger(EKind);
400 ID.AddPointer(Ty.getAsOpaquePtr());
401
402 void *InsertPos = 0;
403 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
404 return DeclarationName(Name);
405
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000406 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000407 SpecialName->ExtraKindOrNumArgs = EKind;
408 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000409 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000410
411 SpecialNames->InsertNode(SpecialName, InsertPos);
412 return DeclarationName(SpecialName);
413}
414
Mike Stump1eb44332009-09-09 15:08:12 +0000415DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000416DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
417 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
418}
419
Sean Hunt3e518bd2009-11-29 07:34:05 +0000420DeclarationName
421DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000422 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
423 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
424 (CXXLiteralOperatorNames);
425
426 llvm::FoldingSetNodeID ID;
427 ID.AddPointer(II);
428
429 void *InsertPos = 0;
430 if (CXXLiteralOperatorIdName *Name =
431 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
432 return DeclarationName (Name);
433
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000434 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000435 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
436 LiteralName->ID = II;
Richard Smith3a5032b2012-03-09 08:37:16 +0000437 LiteralName->FETokenInfo = 0;
Sean Hunta6c058d2010-01-13 09:01:02 +0000438
439 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000440 return DeclarationName(LiteralName);
441}
442
Abramo Bagnara25777432010-08-11 22:01:17 +0000443DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
444 switch (Name.getNameKind()) {
445 case DeclarationName::Identifier:
446 break;
447 case DeclarationName::CXXConstructorName:
448 case DeclarationName::CXXDestructorName:
449 case DeclarationName::CXXConversionFunctionName:
450 NamedType.TInfo = 0;
451 break;
452 case DeclarationName::CXXOperatorName:
453 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
454 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
455 break;
456 case DeclarationName::CXXLiteralOperatorName:
457 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
458 break;
459 case DeclarationName::ObjCZeroArgSelector:
460 case DeclarationName::ObjCOneArgSelector:
461 case DeclarationName::ObjCMultiArgSelector:
462 // FIXME: ?
463 break;
464 case DeclarationName::CXXUsingDirective:
465 break;
466 }
467}
468
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000469bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
470 switch (Name.getNameKind()) {
471 case DeclarationName::Identifier:
472 case DeclarationName::ObjCZeroArgSelector:
473 case DeclarationName::ObjCOneArgSelector:
474 case DeclarationName::ObjCMultiArgSelector:
475 case DeclarationName::CXXOperatorName:
476 case DeclarationName::CXXLiteralOperatorName:
477 case DeclarationName::CXXUsingDirective:
478 return false;
479
480 case DeclarationName::CXXConstructorName:
481 case DeclarationName::CXXDestructorName:
482 case DeclarationName::CXXConversionFunctionName:
483 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
484 return TInfo->getType()->containsUnexpandedParameterPack();
485
486 return Name.getCXXNameType()->containsUnexpandedParameterPack();
487 }
Chandler Carruthf24e54a2010-12-15 07:29:18 +0000488 llvm_unreachable("All name kinds handled.");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000489}
490
Douglas Gregor561f8122011-07-01 01:22:09 +0000491bool DeclarationNameInfo::isInstantiationDependent() const {
492 switch (Name.getNameKind()) {
493 case DeclarationName::Identifier:
494 case DeclarationName::ObjCZeroArgSelector:
495 case DeclarationName::ObjCOneArgSelector:
496 case DeclarationName::ObjCMultiArgSelector:
497 case DeclarationName::CXXOperatorName:
498 case DeclarationName::CXXLiteralOperatorName:
499 case DeclarationName::CXXUsingDirective:
500 return false;
501
502 case DeclarationName::CXXConstructorName:
503 case DeclarationName::CXXDestructorName:
504 case DeclarationName::CXXConversionFunctionName:
505 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
506 return TInfo->getType()->isInstantiationDependentType();
507
508 return Name.getCXXNameType()->isInstantiationDependentType();
509 }
510 llvm_unreachable("All name kinds handled.");
511}
512
Abramo Bagnara25777432010-08-11 22:01:17 +0000513std::string DeclarationNameInfo::getAsString() const {
514 std::string Result;
515 llvm::raw_string_ostream OS(Result);
516 printName(OS);
517 return OS.str();
518}
519
Chris Lattner5f9e2722011-07-23 10:55:15 +0000520void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnara25777432010-08-11 22:01:17 +0000521 switch (Name.getNameKind()) {
522 case DeclarationName::Identifier:
523 case DeclarationName::ObjCZeroArgSelector:
524 case DeclarationName::ObjCOneArgSelector:
525 case DeclarationName::ObjCMultiArgSelector:
526 case DeclarationName::CXXOperatorName:
527 case DeclarationName::CXXLiteralOperatorName:
528 case DeclarationName::CXXUsingDirective:
David Blaikie17828ca2013-05-14 21:04:00 +0000529 OS << Name;
Abramo Bagnara25777432010-08-11 22:01:17 +0000530 return;
531
532 case DeclarationName::CXXConstructorName:
533 case DeclarationName::CXXDestructorName:
534 case DeclarationName::CXXConversionFunctionName:
535 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
536 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
537 OS << '~';
538 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
539 OS << "operator ";
540 OS << TInfo->getType().getAsString();
David Blaikie17828ca2013-05-14 21:04:00 +0000541 } else
542 OS << Name;
Abramo Bagnara25777432010-08-11 22:01:17 +0000543 return;
544 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000545 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000546}
547
548SourceLocation DeclarationNameInfo::getEndLoc() const {
549 switch (Name.getNameKind()) {
550 case DeclarationName::Identifier:
551 return NameLoc;
552
553 case DeclarationName::CXXOperatorName: {
554 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
555 return SourceLocation::getFromRawEncoding(raw);
556 }
557
558 case DeclarationName::CXXLiteralOperatorName: {
559 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
560 return SourceLocation::getFromRawEncoding(raw);
561 }
562
563 case DeclarationName::CXXConstructorName:
564 case DeclarationName::CXXDestructorName:
565 case DeclarationName::CXXConversionFunctionName:
566 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
567 return TInfo->getTypeLoc().getEndLoc();
568 else
569 return NameLoc;
570
571 // DNInfo work in progress: FIXME.
572 case DeclarationName::ObjCZeroArgSelector:
573 case DeclarationName::ObjCOneArgSelector:
574 case DeclarationName::ObjCMultiArgSelector:
575 case DeclarationName::CXXUsingDirective:
576 return NameLoc;
577 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000578 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000579}