blob: 596ecc593e30bd1575538d338453faf074e3236b [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"
Benjamin Kramerf6cde772010-04-17 09:56:45 +000023#include "llvm/Support/raw_ostream.h"
Douglas Gregor2e1cd422008-11-17 14:58:09 +000024using namespace clang;
25
26namespace clang {
27/// CXXSpecialName - Records the type associated with one of the
28/// "special" kinds of declaration names in C++, e.g., constructors,
29/// destructors, and conversion functions.
Mike Stump1eb44332009-09-09 15:08:12 +000030class CXXSpecialName
Douglas Gregor2e1cd422008-11-17 14:58:09 +000031 : public DeclarationNameExtra, public llvm::FoldingSetNode {
32public:
Douglas Gregor2def4832008-11-17 20:34:05 +000033 /// Type - The type associated with this declaration name.
Douglas Gregor2e1cd422008-11-17 14:58:09 +000034 QualType Type;
35
Douglas Gregor2def4832008-11-17 20:34:05 +000036 /// FETokenInfo - Extra information associated with this declaration
37 /// name that can be used by the front end.
38 void *FETokenInfo;
39
Douglas Gregor2e1cd422008-11-17 14:58:09 +000040 void Profile(llvm::FoldingSetNodeID &ID) {
41 ID.AddInteger(ExtraKindOrNumArgs);
42 ID.AddPointer(Type.getAsOpaquePtr());
43 }
44};
45
Douglas Gregore94ca9e42008-11-18 14:39:36 +000046/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump1eb44332009-09-09 15:08:12 +000047/// overloaded operator in C++, such as "operator+.
Douglas Gregore94ca9e42008-11-18 14:39:36 +000048class CXXOperatorIdName : public DeclarationNameExtra {
49public:
50 /// FETokenInfo - Extra information associated with this operator
51 /// name that can be used by the front end.
52 void *FETokenInfo;
53};
54
Sean Hunt3e518bd2009-11-29 07:34:05 +000055/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
56/// name.
57///
58/// This identifier is stored here rather than directly in DeclarationName so as
59/// to allow Objective-C selectors, which are about a million times more common,
60/// to consume minimal memory.
Sean Hunta6c058d2010-01-13 09:01:02 +000061class CXXLiteralOperatorIdName
62 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Sean Hunt3e518bd2009-11-29 07:34:05 +000063public:
64 IdentifierInfo *ID;
Sean Hunta6c058d2010-01-13 09:01:02 +000065
66 void Profile(llvm::FoldingSetNodeID &FSID) {
67 FSID.AddPointer(ID);
68 }
Sean Hunt3e518bd2009-11-29 07:34:05 +000069};
70
John McCall7fe0b9e2010-02-13 01:04:05 +000071static int compareInt(unsigned A, unsigned B) {
72 return (A < B ? -1 : (A > B ? 1 : 0));
73}
74
75int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000076 if (LHS.getNameKind() != RHS.getNameKind())
John McCall7fe0b9e2010-02-13 01:04:05 +000077 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregord6b5f132009-11-04 22:24:30 +000078
79 switch (LHS.getNameKind()) {
John McCall7fe0b9e2010-02-13 01:04:05 +000080 case DeclarationName::Identifier: {
81 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
82 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
83 if (!LII) return RII ? -1 : 0;
84 if (!RII) return 1;
85
86 return LII->getName().compare(RII->getName());
87 }
Douglas Gregor2e1cd422008-11-17 14:58:09 +000088
Douglas Gregord6b5f132009-11-04 22:24:30 +000089 case DeclarationName::ObjCZeroArgSelector:
90 case DeclarationName::ObjCOneArgSelector:
91 case DeclarationName::ObjCMultiArgSelector: {
92 Selector LHSSelector = LHS.getObjCSelector();
93 Selector RHSSelector = RHS.getObjCSelector();
John McCall7fe0b9e2010-02-13 01:04:05 +000094 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
95 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregord6b5f132009-11-04 22:24:30 +000096 IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
97 IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
Douglas Gregord6b5f132009-11-04 22:24:30 +000098
99 switch (LHSId->getName().compare(RHSId->getName())) {
100 case -1: return true;
101 case 1: return false;
102 default: break;
103 }
104 }
John McCall7fe0b9e2010-02-13 01:04:05 +0000105
106 return compareInt(LN, RN);
Douglas Gregord6b5f132009-11-04 22:24:30 +0000107 }
108
109 case DeclarationName::CXXConstructorName:
110 case DeclarationName::CXXDestructorName:
111 case DeclarationName::CXXConversionFunctionName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000112 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
113 return -1;
114 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
115 return 1;
116 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000117
118 case DeclarationName::CXXOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000119 return compareInt(LHS.getCXXOverloadedOperator(),
120 RHS.getCXXOverloadedOperator());
Sean Hunt3e518bd2009-11-29 07:34:05 +0000121
122 case DeclarationName::CXXLiteralOperatorName:
John McCall7fe0b9e2010-02-13 01:04:05 +0000123 return LHS.getCXXLiteralIdentifier()->getName().compare(
124 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregord6b5f132009-11-04 22:24:30 +0000125
126 case DeclarationName::CXXUsingDirective:
John McCall7fe0b9e2010-02-13 01:04:05 +0000127 return 0;
Douglas Gregord6b5f132009-11-04 22:24:30 +0000128 }
129
John McCall7fe0b9e2010-02-13 01:04:05 +0000130 return 0;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000131}
132
133} // end namespace clang
134
135DeclarationName::DeclarationName(Selector Sel) {
Douglas Gregor319ac892009-04-23 22:29:11 +0000136 if (!Sel.getAsOpaquePtr()) {
Douglas Gregor813a97b2009-10-17 17:25:45 +0000137 Ptr = 0;
Douglas Gregor319ac892009-04-23 22:29:11 +0000138 return;
139 }
140
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000141 switch (Sel.getNumArgs()) {
142 case 0:
143 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000144 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000145 Ptr |= StoredObjCZeroArgSelector;
146 break;
147
148 case 1:
149 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000150 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000151 Ptr |= StoredObjCOneArgSelector;
152 break;
153
154 default:
155 Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ted Kremenek3eb8dd72009-03-14 00:27:40 +0000156 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000157 Ptr |= StoredDeclarationNameExtra;
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000158 break;
159 }
160}
161
162DeclarationName::NameKind DeclarationName::getNameKind() const {
163 switch (getStoredNameKind()) {
164 case StoredIdentifier: return Identifier;
165 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
166 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
167
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000168 case StoredDeclarationNameExtra:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000169 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump1eb44332009-09-09 15:08:12 +0000170 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000171 return CXXConstructorName;
172
Mike Stump1eb44332009-09-09 15:08:12 +0000173 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000174 return CXXDestructorName;
175
Mike Stump1eb44332009-09-09 15:08:12 +0000176 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000177 return CXXConversionFunctionName;
178
Sean Hunt3e518bd2009-11-29 07:34:05 +0000179 case DeclarationNameExtra::CXXLiteralOperator:
180 return CXXLiteralOperatorName;
181
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000182 case DeclarationNameExtra::CXXUsingDirective:
183 return CXXUsingDirective;
184
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000185 default:
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000186 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump1eb44332009-09-09 15:08:12 +0000187 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000188 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000189 return CXXOperatorName;
190
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000191 return ObjCMultiArgSelector;
192 }
193 break;
194 }
195
196 // Can't actually get here.
Chris Lattnerac8d75f2009-03-21 06:40:50 +0000197 assert(0 && "This should be unreachable!");
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000198 return Identifier;
199}
200
Douglas Gregor48026d22010-01-11 18:40:55 +0000201bool DeclarationName::isDependentName() const {
202 QualType T = getCXXNameType();
203 return !T.isNull() && T->isDependentType();
204}
205
Douglas Gregor10bd3682008-11-17 22:58:34 +0000206std::string DeclarationName::getAsString() const {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000207 std::string Result;
208 llvm::raw_string_ostream OS(Result);
209 printName(OS);
210 return OS.str();
211}
212
213void DeclarationName::printName(llvm::raw_ostream &OS) const {
Douglas Gregor10bd3682008-11-17 22:58:34 +0000214 switch (getNameKind()) {
215 case Identifier:
216 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000217 OS << II->getName();
218 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000219
220 case ObjCZeroArgSelector:
221 case ObjCOneArgSelector:
222 case ObjCMultiArgSelector:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000223 OS << getObjCSelector().getAsString();
224 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000225
226 case CXXConstructorName: {
227 QualType ClassType = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000228 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000229 OS << ClassRec->getDecl();
230 else
231 OS << ClassType.getAsString();
232 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000233 }
234
235 case CXXDestructorName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000236 OS << '~';
Douglas Gregor10bd3682008-11-17 22:58:34 +0000237 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000238 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000239 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000240 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000241 OS << Type.getAsString();
242 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000243 }
244
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000245 case CXXOperatorName: {
Nuno Lopes2550d702009-12-23 17:49:57 +0000246 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000247 0,
248#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
249 Spelling,
250#include "clang/Basic/OperatorKinds.def"
251 };
252 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
253 assert(OpName && "not an overloaded operator");
Mike Stump1eb44332009-09-09 15:08:12 +0000254
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000255 OS << "operator";
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000256 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000257 OS << ' ';
258 OS << OpName;
259 return;
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000260 }
261
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000262 case CXXLiteralOperatorName:
263 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
264 return;
Sean Hunt3e518bd2009-11-29 07:34:05 +0000265
Douglas Gregor10bd3682008-11-17 22:58:34 +0000266 case CXXConversionFunctionName: {
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000267 OS << "operator ";
Douglas Gregor10bd3682008-11-17 22:58:34 +0000268 QualType Type = getCXXNameType();
Ted Kremenek6217b802009-07-29 21:53:49 +0000269 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000270 OS << Rec->getDecl();
Douglas Gregor10bd3682008-11-17 22:58:34 +0000271 else
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000272 OS << Type.getAsString();
273 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000274 }
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000275 case CXXUsingDirective:
Benjamin Kramerf6cde772010-04-17 09:56:45 +0000276 OS << "<using-directive>";
277 return;
Douglas Gregor10bd3682008-11-17 22:58:34 +0000278 }
279
280 assert(false && "Unexpected declaration name kind");
Douglas Gregor10bd3682008-11-17 22:58:34 +0000281}
282
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000283QualType DeclarationName::getCXXNameType() const {
284 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
285 return CXXName->Type;
286 else
287 return QualType();
288}
289
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000290OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
291 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000292 unsigned value
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000293 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
294 return static_cast<OverloadedOperatorKind>(value);
295 } else {
296 return OO_None;
297 }
298}
299
Sean Hunt3e518bd2009-11-29 07:34:05 +0000300IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
301 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
302 return CXXLit->ID;
303 else
304 return 0;
305}
306
Douglas Gregor2e1cd422008-11-17 14:58:09 +0000307Selector DeclarationName::getObjCSelector() const {
308 switch (getNameKind()) {
309 case ObjCZeroArgSelector:
310 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
311
312 case ObjCOneArgSelector:
313 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
314
315 case ObjCMultiArgSelector:
316 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
317
318 default:
319 break;
320 }
321
322 return Selector();
323}
324
Douglas Gregor2def4832008-11-17 20:34:05 +0000325void *DeclarationName::getFETokenInfoAsVoid() const {
326 switch (getNameKind()) {
327 case Identifier:
328 return getAsIdentifierInfo()->getFETokenInfo<void>();
329
330 case CXXConstructorName:
331 case CXXDestructorName:
332 case CXXConversionFunctionName:
333 return getAsCXXSpecialName()->FETokenInfo;
334
Douglas Gregore94ca9e42008-11-18 14:39:36 +0000335 case CXXOperatorName:
336 return getAsCXXOperatorIdName()->FETokenInfo;
337
Sean Hunt3e518bd2009-11-29 07:34:05 +0000338 case CXXLiteralOperatorName:
339 return getCXXLiteralIdentifier()->getFETokenInfo<void>();
340
Douglas Gregor2def4832008-11-17 20:34:05 +0000341 default:
342 assert(false && "Declaration name has no FETokenInfo");
343 }
344 return 0;
345}
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:
364 getCXXLiteralIdentifier()->setFETokenInfo(T);
365 break;
366
Douglas Gregor2def4832008-11-17 20:34:05 +0000367 default:
368 assert(false && "Declaration name has no FETokenInfo");
369 }
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
Ted Kremenek45d9c2d2010-05-10 20:56:10 +0000388DeclarationNameTable::DeclarationNameTable(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;
Sean Hunta6c058d2010-01-13 09:01:02 +0000478
479 LiteralNames->InsertNode(LiteralName, InsertPos);
Sean Hunt3e518bd2009-11-29 07:34:05 +0000480 return DeclarationName(LiteralName);
481}
482
Mike Stump1eb44332009-09-09 15:08:12 +0000483unsigned
Douglas Gregor44b43212008-12-11 16:49:14 +0000484llvm::DenseMapInfo<clang::DeclarationName>::
485getHashValue(clang::DeclarationName N) {
486 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
487}
488
Abramo Bagnara25777432010-08-11 22:01:17 +0000489DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
490 switch (Name.getNameKind()) {
491 case DeclarationName::Identifier:
492 break;
493 case DeclarationName::CXXConstructorName:
494 case DeclarationName::CXXDestructorName:
495 case DeclarationName::CXXConversionFunctionName:
496 NamedType.TInfo = 0;
497 break;
498 case DeclarationName::CXXOperatorName:
499 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
500 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
501 break;
502 case DeclarationName::CXXLiteralOperatorName:
503 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
504 break;
505 case DeclarationName::ObjCZeroArgSelector:
506 case DeclarationName::ObjCOneArgSelector:
507 case DeclarationName::ObjCMultiArgSelector:
508 // FIXME: ?
509 break;
510 case DeclarationName::CXXUsingDirective:
511 break;
512 }
513}
514
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000515bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
516 switch (Name.getNameKind()) {
517 case DeclarationName::Identifier:
518 case DeclarationName::ObjCZeroArgSelector:
519 case DeclarationName::ObjCOneArgSelector:
520 case DeclarationName::ObjCMultiArgSelector:
521 case DeclarationName::CXXOperatorName:
522 case DeclarationName::CXXLiteralOperatorName:
523 case DeclarationName::CXXUsingDirective:
524 return false;
525
526 case DeclarationName::CXXConstructorName:
527 case DeclarationName::CXXDestructorName:
528 case DeclarationName::CXXConversionFunctionName:
529 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
530 return TInfo->getType()->containsUnexpandedParameterPack();
531
532 return Name.getCXXNameType()->containsUnexpandedParameterPack();
533 }
534}
535
Abramo Bagnara25777432010-08-11 22:01:17 +0000536std::string DeclarationNameInfo::getAsString() const {
537 std::string Result;
538 llvm::raw_string_ostream OS(Result);
539 printName(OS);
540 return OS.str();
541}
542
543void DeclarationNameInfo::printName(llvm::raw_ostream &OS) const {
544 switch (Name.getNameKind()) {
545 case DeclarationName::Identifier:
546 case DeclarationName::ObjCZeroArgSelector:
547 case DeclarationName::ObjCOneArgSelector:
548 case DeclarationName::ObjCMultiArgSelector:
549 case DeclarationName::CXXOperatorName:
550 case DeclarationName::CXXLiteralOperatorName:
551 case DeclarationName::CXXUsingDirective:
552 Name.printName(OS);
553 return;
554
555 case DeclarationName::CXXConstructorName:
556 case DeclarationName::CXXDestructorName:
557 case DeclarationName::CXXConversionFunctionName:
558 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
559 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
560 OS << '~';
561 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
562 OS << "operator ";
563 OS << TInfo->getType().getAsString();
564 }
565 else
566 Name.printName(OS);
567 return;
568 }
569 assert(false && "Unexpected declaration name kind");
570}
571
572SourceLocation DeclarationNameInfo::getEndLoc() const {
573 switch (Name.getNameKind()) {
574 case DeclarationName::Identifier:
575 return NameLoc;
576
577 case DeclarationName::CXXOperatorName: {
578 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
579 return SourceLocation::getFromRawEncoding(raw);
580 }
581
582 case DeclarationName::CXXLiteralOperatorName: {
583 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
584 return SourceLocation::getFromRawEncoding(raw);
585 }
586
587 case DeclarationName::CXXConstructorName:
588 case DeclarationName::CXXDestructorName:
589 case DeclarationName::CXXConversionFunctionName:
590 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
591 return TInfo->getTypeLoc().getEndLoc();
592 else
593 return NameLoc;
594
595 // DNInfo work in progress: FIXME.
596 case DeclarationName::ObjCZeroArgSelector:
597 case DeclarationName::ObjCOneArgSelector:
598 case DeclarationName::ObjCMultiArgSelector:
599 case DeclarationName::CXXUsingDirective:
600 return NameLoc;
601 }
602 assert(false && "Unexpected declaration name kind");
603 return SourceLocation();
604}