blob: ac3989bbb8ebfc1259b50ade2cccbf44f4129597 [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 Gregord6b5f132009-11-04 22:24:30 +000097 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
98 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
Douglas Gregord6b5f132009-11-04 22:24:30 +000099
100 switch (LHSId->getName().compare(RHSId->getName())) {
101 case -1: return true;
102 case 1: return false;
103 default: break;
104 }
105 }
John McCall7fe0b9e2010-02-13 01:04:05 +0000106
107 return compareInt(LN, RN);
Douglas Gregord6b5f132009-11-04 22:24:30 +0000108 }
109
110 case DeclarationName::CXXConstructorName:
111 case DeclarationName::CXXDestructorName:
112 case DeclarationName::CXXConversionFunctionName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000113 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
114 return -1;
115 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
116 return 1;
117 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000118
119 case DeclarationName::CXXOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000120 return compareInt(LHS.getCXXOverloadedOperator(),
121 RHS.getCXXOverloadedOperator());
Sean Hunt3e518bd2009-11-29 07:34:05 +0000122
123 case DeclarationName::CXXLiteralOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000124 return LHS.getCXXLiteralIdentifier()->getName().compare(
125 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregord6b5f132009-11-04 22:24:30 +0000126
127 case DeclarationName::CXXUsingDirective:
John McCall7fe0b9e2010-02-13 01:04:05 +0000128 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000129 }
130
John McCall7fe0b9e2010-02-13 01:04:05 +0000131 return 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000132}
133
134} // end namespace clang
135
136DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000137 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000138 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000139 return;
140 }
141
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000142 switch (Sel.getNumArgs()) {
143 case 0:
144 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000145 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000146 Ptr |= StoredObjCZeroArgSelector;
147 break;
148
149 case 1:
150 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000151 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000152 Ptr |= StoredObjCOneArgSelector;
153 break;
154
155 default:
156 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000157 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000158 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000159 break;
160 }
161}
162
163DeclarationName::NameKind DeclarationName::getNameKind() const {
164 switch (getStoredNameKind()) {
165 case StoredIdentifier: return Identifier;
166 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
167 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
168
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000169 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000170 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000171 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000172 return CXXConstructorName;
173
Mike Stump1eb44332009-09-09 15:08:12 +0000174 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000175 return CXXDestructorName;
176
Mike Stump1eb44332009-09-09 15:08:12 +0000177 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000178 return CXXConversionFunctionName;
179
Sean Hunt3e518bd2009-11-29 07:34:05 +0000180 case DeclarationNameExtra::CXXLiteralOperator:
181 return CXXLiteralOperatorName;
182
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000183 case DeclarationNameExtra::CXXUsingDirective:
184 return CXXUsingDirective;
185
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000186 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000187 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000188 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000189 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000190 return CXXOperatorName;
191
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000192 return ObjCMultiArgSelector;
193 }
194 break;
195 }
196
197 // Can't actually get here.
Chris Lattnerac8d75f2009-03-21 06:40:50 +0000198 assert(0 && "This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000199 return Identifier;
200}
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
214void DeclarationName::printName(llvm::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 Kramerf6cde772010-04-17 09:56:45 +0000230 OS << ClassRec->getDecl();
231 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 Kramerf6cde772010-04-17 09:56:45 +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 Kramerf6cde772010-04-17 09:56:45 +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
281 assert(false && "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 Gregor2def4832008-11-17 20:34:05 +0000326void *DeclarationName::getFETokenInfoAsVoid() const {
327 switch (getNameKind()) {
328 case Identifier:
329 return getAsIdentifierInfo()->getFETokenInfo<void>();
330
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:
340 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
341
Douglas Gregor2def4832008-11-17 20:34:05 +0000342 default:
343 assert(false && "Declaration name has no FETokenInfo");
344 }
345 return 0;
346}
347
348void DeclarationName::setFETokenInfo(void *T) {
349 switch (getNameKind()) {
350 case Identifier:
351 getAsIdentifierInfo()->setFETokenInfo(T);
352 break;
353
354 case CXXConstructorName:
355 case CXXDestructorName:
356 case CXXConversionFunctionName:
357 getAsCXXSpecialName()->FETokenInfo = T;
358 break;
359
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000360 case CXXOperatorName:
361 getAsCXXOperatorIdName()->FETokenInfo = T;
362 break;
363
Sean Hunt3e518bd2009-11-29 07:34:05 +0000364 case CXXLiteralOperatorName:
365 getCXXLiteralIdentifier()->setFETokenInfo(T);
366 break;
367
Douglas Gregor2def4832008-11-17 20:34:05 +0000368 default:
369 assert(false && "Declaration name has no FETokenInfo");
370 }
371}
372
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000373DeclarationName DeclarationName::getUsingDirectiveName() {
374 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes68f7a242009-12-10 00:07:02 +0000375 static const DeclarationNameExtra UDirExtra =
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000376 { DeclarationNameExtra::CXXUsingDirective };
377
378 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
379 Ptr |= StoredDeclarationNameExtra;
380
381 return DeclarationName(Ptr);
382}
383
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000384void DeclarationName::dump() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000385 printName(llvm::errs());
386 llvm::errs() << '\n';
Anders Carlsson70f5bc72009-11-15 22:30:43 +0000387}
388
Jay Foad4ba2a172011-01-12 09:06:06 +0000389DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000390 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Sean Hunta6c058d2010-01-13 09:01:02 +0000391 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000392
393 // Initialize the overloaded operator names.
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000394 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000395 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump1eb44332009-09-09 15:08:12 +0000396 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000397 = Op + DeclarationNameExtra::CXXConversionFunction;
398 CXXOperatorNames[Op].FETokenInfo = 0;
399 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000400}
401
402DeclarationNameTable::~DeclarationNameTable() {
Sean Hunta6c058d2010-01-13 09:01:02 +0000403 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes6d34ae52008-12-14 17:27:25 +0000404 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Sean Hunta6c058d2010-01-13 09:01:02 +0000405 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
406 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000407 (CXXLiteralOperatorNames);
Sean Hunta6c058d2010-01-13 09:01:02 +0000408
Sean Hunta6c058d2010-01-13 09:01:02 +0000409 delete SpecialNames;
410 delete LiteralNames;
Ted Kremenekac9590e2010-05-10 20:40:08 +0000411}
412
Mike Stump1eb44332009-09-09 15:08:12 +0000413DeclarationName
414DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor50d62d12009-08-05 05:36:45 +0000415 CanQualType Ty) {
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000416 assert(Kind >= DeclarationName::CXXConstructorName &&
417 Kind <= DeclarationName::CXXConversionFunctionName &&
418 "Kind must be a C++ special name kind");
Mike Stump1eb44332009-09-09 15:08:12 +0000419 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000420 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
421
422 DeclarationNameExtra::ExtraKind EKind;
423 switch (Kind) {
Mike Stump1eb44332009-09-09 15:08:12 +0000424 case DeclarationName::CXXConstructorName:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000425 EKind = DeclarationNameExtra::CXXConstructor;
John McCall0953e762009-09-24 19:53:00 +0000426 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000427 break;
428 case DeclarationName::CXXDestructorName:
429 EKind = DeclarationNameExtra::CXXDestructor;
John McCall0953e762009-09-24 19:53:00 +0000430 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000431 break;
432 case DeclarationName::CXXConversionFunctionName:
433 EKind = DeclarationNameExtra::CXXConversionFunction;
434 break;
435 default:
436 return DeclarationName();
437 }
438
439 // Unique selector, to guarantee there is one per name.
440 llvm::FoldingSetNodeID ID;
441 ID.AddInteger(EKind);
442 ID.AddPointer(Ty.getAsOpaquePtr());
443
444 void *InsertPos = 0;
445 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
446 return DeclarationName(Name);
447
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000448 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000449 SpecialName->ExtraKindOrNumArgs = EKind;
450 SpecialName->Type = Ty;
Douglas Gregor2def4832008-11-17 20:34:05 +0000451 SpecialName->FETokenInfo = 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000452
453 SpecialNames->InsertNode(SpecialName, InsertPos);
454 return DeclarationName(SpecialName);
455}
456
Mike Stump1eb44332009-09-09 15:08:12 +0000457DeclarationName
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000458DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
459 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
460}
461
Sean Hunt3e518bd2009-11-29 07:34:05 +0000462DeclarationName
463DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Sean Hunta6c058d2010-01-13 09:01:02 +0000464 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
465 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
466 (CXXLiteralOperatorNames);
467
468 llvm::FoldingSetNodeID ID;
469 ID.AddPointer(II);
470
471 void *InsertPos = 0;
472 if (CXXLiteralOperatorIdName *Name =
473 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
474 return DeclarationName (Name);
475
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000476 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000477 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
478 LiteralName->ID = II;
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
Abramo Bagnara25777432010-08-11 22:01:17 +0000538std::string DeclarationNameInfo::getAsString() const {
539 std::string Result;
540 llvm::raw_string_ostream OS(Result);
541 printName(OS);
542 return OS.str();
543}
544
545void DeclarationNameInfo::printName(llvm::raw_ostream &OS) const {
546 switch (Name.getNameKind()) {
547 case DeclarationName::Identifier:
548 case DeclarationName::ObjCZeroArgSelector:
549 case DeclarationName::ObjCOneArgSelector:
550 case DeclarationName::ObjCMultiArgSelector:
551 case DeclarationName::CXXOperatorName:
552 case DeclarationName::CXXLiteralOperatorName:
553 case DeclarationName::CXXUsingDirective:
554 Name.printName(OS);
555 return;
556
557 case DeclarationName::CXXConstructorName:
558 case DeclarationName::CXXDestructorName:
559 case DeclarationName::CXXConversionFunctionName:
560 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
561 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
562 OS << '~';
563 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
564 OS << "operator ";
565 OS << TInfo->getType().getAsString();
566 }
567 else
568 Name.printName(OS);
569 return;
570 }
571 assert(false && "Unexpected declaration name kind");
572}
573
574SourceLocation DeclarationNameInfo::getEndLoc() const {
575 switch (Name.getNameKind()) {
576 case DeclarationName::Identifier:
577 return NameLoc;
578
579 case DeclarationName::CXXOperatorName: {
580 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
581 return SourceLocation::getFromRawEncoding(raw);
582 }
583
584 case DeclarationName::CXXLiteralOperatorName: {
585 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
586 return SourceLocation::getFromRawEncoding(raw);
587 }
588
589 case DeclarationName::CXXConstructorName:
590 case DeclarationName::CXXDestructorName:
591 case DeclarationName::CXXConversionFunctionName:
592 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
593 return TInfo->getTypeLoc().getEndLoc();
594 else
595 return NameLoc;
596
597 // DNInfo work in progress: FIXME.
598 case DeclarationName::ObjCZeroArgSelector:
599 case DeclarationName::ObjCOneArgSelector:
600 case DeclarationName::ObjCMultiArgSelector:
601 case DeclarationName::CXXUsingDirective:
602 return NameLoc;
603 }
604 assert(false && "Unexpected declaration name kind");
605 return SourceLocation();
606}