blob: a5488e67ca234e51a56929f8e2c7088488fcd536 [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 }
David Blaikie30263482012-01-20 21:50:17 +0000128
129 llvm_unreachable("Invalid DeclarationName Kind!");
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 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000192 }
193
194 // Can't actually get here.
David Blaikieb219cfc2011-09-23 05:06:16 +0000195 llvm_unreachable("This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000196}
197
Douglas Gregor48026d22010-01-11 18:40:55 +0000198bool DeclarationName::isDependentName() const {
199 QualType T = getCXXNameType();
200 return !T.isNull() && T->isDependentType();
201}
202
Douglas Gregor10bd3682008-11-17 22:58:34 +0000203std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000204 std::string Result;
205 llvm::raw_string_ostream OS(Result);
206 printName(OS);
207 return OS.str();
208}
209
Chris Lattner5f9e2722011-07-23 10:55:15 +0000210void DeclarationName::printName(raw_ostream &OS) const {
Douglas Gregor10bd3682008-11-17 22:58:34 +0000211 switch (getNameKind()) {
212 case Identifier:
213 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000214 OS << II->getName();
215 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000216
217 case ObjCZeroArgSelector:
218 case ObjCOneArgSelector:
219 case ObjCMultiArgSelector:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000220 OS << getObjCSelector().getAsString();
221 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000222
223 case CXXConstructorName: {
224 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000225 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000226 OS << *ClassRec->getDecl();
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000227 else
228 OS << ClassType.getAsString();
229 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000230 }
231
232 case CXXDestructorName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000233 OS << '~';
Douglas Gregor10bd3682008-11-17 22:58:34 +0000234 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000235 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000236 OS << *Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000237 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000238 OS << Type.getAsString();
239 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000240 }
241
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000242 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000243 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000244 0,
245#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
246 Spelling,
247#include "clang/Basic/OperatorKinds.def"
248 };
249 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
250 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000251
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000252 OS << "operator";
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000253 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000254 OS << ' ';
255 OS << OpName;
256 return;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000257 }
258
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000259 case CXXLiteralOperatorName:
260 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
261 return;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000262
Douglas Gregor10bd3682008-11-17 22:58:34 +0000263 case CXXConversionFunctionName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000264 OS << "operator ";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000265 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000266 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb8989f22011-10-14 18:45:37 +0000267 OS << *Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000268 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000269 OS << Type.getAsString();
270 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000271 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000272 case CXXUsingDirective:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000273 OS << "<using-directive>";
274 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000275 }
276
David Blaikieb219cfc2011-09-23 05:06:16 +0000277 llvm_unreachable("Unexpected declaration name kind");
Douglas Gregor10bd3682008-11-17 22:58:34 +0000278}
279
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000280QualType DeclarationName::getCXXNameType() const {
281 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
282 return CXXName->Type;
283 else
284 return QualType();
285}
286
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000287OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
288 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000289 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000290 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
291 return static_cast<OverloadedOperatorKind>(value);
292 } else {
293 return OO_None;
294 }
295}
296
Sean Hunt3e518bd2009-11-29 07:34:05 +0000297IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
298 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
299 return CXXLit->ID;
300 else
301 return 0;
302}
303
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000304Selector DeclarationName::getObjCSelector() const {
305 switch (getNameKind()) {
306 case ObjCZeroArgSelector:
307 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
308
309 case ObjCOneArgSelector:
310 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
311
312 case ObjCMultiArgSelector:
313 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
314
315 default:
316 break;
317 }
318
319 return Selector();
320}
321
Douglas Gregor2def4832008-11-17 20:34:05 +0000322void *DeclarationName::getFETokenInfoAsVoid() const {
323 switch (getNameKind()) {
324 case Identifier:
325 return getAsIdentifierInfo()->getFETokenInfo<void>();
326
327 case CXXConstructorName:
328 case CXXDestructorName:
329 case CXXConversionFunctionName:
330 return getAsCXXSpecialName()->FETokenInfo;
331
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000332 case CXXOperatorName:
333 return getAsCXXOperatorIdName()->FETokenInfo;
334
Sean Hunt3e518bd2009-11-29 07:34:05 +0000335 case CXXLiteralOperatorName:
336 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
337
Douglas Gregor2def4832008-11-17 20:34:05 +0000338 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000339 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000340 }
Douglas Gregor2def4832008-11-17 20:34:05 +0000341}
342
343void DeclarationName::setFETokenInfo(void *T) {
344 switch (getNameKind()) {
345 case Identifier:
346 getAsIdentifierInfo()->setFETokenInfo(T);
347 break;
348
349 case CXXConstructorName:
350 case CXXDestructorName:
351 case CXXConversionFunctionName:
352 getAsCXXSpecialName()->FETokenInfo = T;
353 break;
354
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000355 case CXXOperatorName:
356 getAsCXXOperatorIdName()->FETokenInfo = T;
357 break;
358
Sean Hunt3e518bd2009-11-29 07:34:05 +0000359 case CXXLiteralOperatorName:
360 getCXXLiteralIdentifier()->setFETokenInfo(T);
361 break;
362
Douglas Gregor2def4832008-11-17 20:34:05 +0000363 default:
David Blaikieb219cfc2011-09-23 05:06:16 +0000364 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregor2def4832008-11-17 20:34:05 +0000365 }
366}
367
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000368DeclarationName DeclarationName::getUsingDirectiveName() {
369 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000370 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000371 { DeclarationNameExtra::CXXUsingDirective };
372
373 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
374 Ptr |= StoredDeclarationNameExtra;
375
376 return DeclarationName(Ptr);
377}
378
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000379void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000380 printName(llvm::errs());
381 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000382}
383
Jay Foad4ba2a172011-01-12 09:06:06 +0000384DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000385 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000386 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000387
388 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000389 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000390 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000391 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000392 = Op + DeclarationNameExtra::CXXConversionFunction;
393 CXXOperatorNames[Op].FETokenInfo = 0;
394 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000395}
396
397DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000398 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000399 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000400 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
401 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000402 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000403
Sean Hunta6c058d2010-01-13 09:01:02 +0000404 delete SpecialNames;
405 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000406}
407
Mike Stump1eb44332009-09-09 15:08:12 +0000408DeclarationName
409DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000410 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000411 assert(Kind >= DeclarationName::CXXConstructorName &&
412 Kind <= DeclarationName::CXXConversionFunctionName &&
413 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000414 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000415 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
416
417 DeclarationNameExtra::ExtraKind EKind;
418 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000419 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000420 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000421 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000422 break;
423 case DeclarationName::CXXDestructorName:
424 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000425 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000426 break;
427 case DeclarationName::CXXConversionFunctionName:
428 EKind = DeclarationNameExtra::CXXConversionFunction;
429 break;
430 default:
431 return DeclarationName();
432 }
433
434 // Unique selector, to guarantee there is one per name.
435 llvm::FoldingSetNodeID ID;
436 ID.AddInteger(EKind);
437 ID.AddPointer(Ty.getAsOpaquePtr());
438
439 void *InsertPos = 0;
440 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
441 return DeclarationName(Name);
442
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000443 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000444 SpecialName->ExtraKindOrNumArgs = EKind;
445 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000446 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000447
448 SpecialNames->InsertNode(SpecialName, InsertPos);
449 return DeclarationName(SpecialName);
450}
451
Mike Stump1eb44332009-09-09 15:08:12 +0000452DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000453DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
454 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
455}
456
Sean Hunt3e518bd2009-11-29 07:34:05 +0000457DeclarationName
458DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000459 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
460 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
461 (CXXLiteralOperatorNames);
462
463 llvm::FoldingSetNodeID ID;
464 ID.AddPointer(II);
465
466 void *InsertPos = 0;
467 if (CXXLiteralOperatorIdName *Name =
468 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
469 return DeclarationName (Name);
470
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000471 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000472 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
473 LiteralName->ID = II;
Sean Hunta6c058d2010-01-13 09:01:02 +0000474
475 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000476 return DeclarationName(LiteralName);
477}
478
Mike Stump1eb44332009-09-09 15:08:12 +0000479unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000480llvm::DenseMapInfo<clang::DeclarationName>::
481getHashValue(clang::DeclarationName N) {
482 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
483}
484
Abramo Bagnara25777432010-08-11 22:01:17 +0000485DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
486 switch (Name.getNameKind()) {
487 case DeclarationName::Identifier:
488 break;
489 case DeclarationName::CXXConstructorName:
490 case DeclarationName::CXXDestructorName:
491 case DeclarationName::CXXConversionFunctionName:
492 NamedType.TInfo = 0;
493 break;
494 case DeclarationName::CXXOperatorName:
495 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
496 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
497 break;
498 case DeclarationName::CXXLiteralOperatorName:
499 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
500 break;
501 case DeclarationName::ObjCZeroArgSelector:
502 case DeclarationName::ObjCOneArgSelector:
503 case DeclarationName::ObjCMultiArgSelector:
504 // FIXME: ?
505 break;
506 case DeclarationName::CXXUsingDirective:
507 break;
508 }
509}
510
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000511bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
512 switch (Name.getNameKind()) {
513 case DeclarationName::Identifier:
514 case DeclarationName::ObjCZeroArgSelector:
515 case DeclarationName::ObjCOneArgSelector:
516 case DeclarationName::ObjCMultiArgSelector:
517 case DeclarationName::CXXOperatorName:
518 case DeclarationName::CXXLiteralOperatorName:
519 case DeclarationName::CXXUsingDirective:
520 return false;
521
522 case DeclarationName::CXXConstructorName:
523 case DeclarationName::CXXDestructorName:
524 case DeclarationName::CXXConversionFunctionName:
525 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
526 return TInfo->getType()->containsUnexpandedParameterPack();
527
528 return Name.getCXXNameType()->containsUnexpandedParameterPack();
529 }
Chandler Carruthf24e54a2010-12-15 07:29:18 +0000530 llvm_unreachable("All name kinds handled.");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000531}
532
Douglas Gregor561f8122011-07-01 01:22:09 +0000533bool DeclarationNameInfo::isInstantiationDependent() const {
534 switch (Name.getNameKind()) {
535 case DeclarationName::Identifier:
536 case DeclarationName::ObjCZeroArgSelector:
537 case DeclarationName::ObjCOneArgSelector:
538 case DeclarationName::ObjCMultiArgSelector:
539 case DeclarationName::CXXOperatorName:
540 case DeclarationName::CXXLiteralOperatorName:
541 case DeclarationName::CXXUsingDirective:
542 return false;
543
544 case DeclarationName::CXXConstructorName:
545 case DeclarationName::CXXDestructorName:
546 case DeclarationName::CXXConversionFunctionName:
547 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
548 return TInfo->getType()->isInstantiationDependentType();
549
550 return Name.getCXXNameType()->isInstantiationDependentType();
551 }
552 llvm_unreachable("All name kinds handled.");
553}
554
Abramo Bagnara25777432010-08-11 22:01:17 +0000555std::string DeclarationNameInfo::getAsString() const {
556 std::string Result;
557 llvm::raw_string_ostream OS(Result);
558 printName(OS);
559 return OS.str();
560}
561
Chris Lattner5f9e2722011-07-23 10:55:15 +0000562void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnara25777432010-08-11 22:01:17 +0000563 switch (Name.getNameKind()) {
564 case DeclarationName::Identifier:
565 case DeclarationName::ObjCZeroArgSelector:
566 case DeclarationName::ObjCOneArgSelector:
567 case DeclarationName::ObjCMultiArgSelector:
568 case DeclarationName::CXXOperatorName:
569 case DeclarationName::CXXLiteralOperatorName:
570 case DeclarationName::CXXUsingDirective:
571 Name.printName(OS);
572 return;
573
574 case DeclarationName::CXXConstructorName:
575 case DeclarationName::CXXDestructorName:
576 case DeclarationName::CXXConversionFunctionName:
577 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
578 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
579 OS << '~';
580 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
581 OS << "operator ";
582 OS << TInfo->getType().getAsString();
583 }
584 else
585 Name.printName(OS);
586 return;
587 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000588 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000589}
590
591SourceLocation DeclarationNameInfo::getEndLoc() const {
592 switch (Name.getNameKind()) {
593 case DeclarationName::Identifier:
594 return NameLoc;
595
596 case DeclarationName::CXXOperatorName: {
597 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
598 return SourceLocation::getFromRawEncoding(raw);
599 }
600
601 case DeclarationName::CXXLiteralOperatorName: {
602 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
603 return SourceLocation::getFromRawEncoding(raw);
604 }
605
606 case DeclarationName::CXXConstructorName:
607 case DeclarationName::CXXDestructorName:
608 case DeclarationName::CXXConversionFunctionName:
609 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
610 return TInfo->getTypeLoc().getEndLoc();
611 else
612 return NameLoc;
613
614 // DNInfo work in progress: FIXME.
615 case DeclarationName::ObjCZeroArgSelector:
616 case DeclarationName::ObjCOneArgSelector:
617 case DeclarationName::ObjCMultiArgSelector:
618 case DeclarationName::CXXUsingDirective:
619 return NameLoc;
620 }
David Blaikieb219cfc2011-09-23 05:06:16 +0000621 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnara25777432010-08-11 22:01:17 +0000622}