blob: 9eadf3254375081da447051025091cbb4f9a4122 [file] [log] [blame]
Douglas Gregor77324f32008-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 Kremenek6aead3a2010-05-10 20:40:08 +000014#include "clang/AST/ASTContext.h"
15#include "clang/AST/Decl.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000016#include "clang/AST/DeclarationName.h"
Douglas Gregor92751d42008-11-17 22:58:34 +000017#include "clang/AST/Type.h"
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000018#include "clang/AST/TypeLoc.h"
Douglas Gregorb082bab2009-11-04 22:24:30 +000019#include "clang/AST/TypeOrdering.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000020#include "clang/Basic/IdentifierTable.h"
Douglas Gregor48db39d2009-04-22 21:45:53 +000021#include "llvm/ADT/DenseMap.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000022#include "llvm/ADT/FoldingSet.h"
Chandler Carruth2b59fbe2010-12-15 07:29:18 +000023#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer95c7c422010-04-17 09:56:45 +000024#include "llvm/Support/raw_ostream.h"
Douglas Gregor77324f32008-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 Stump11289f42009-09-09 15:08:12 +000031class CXXSpecialName
Douglas Gregor77324f32008-11-17 14:58:09 +000032 : public DeclarationNameExtra, public llvm::FoldingSetNode {
33public:
Douglas Gregorae2fbad2008-11-17 20:34:05 +000034 /// Type - The type associated with this declaration name.
Douglas Gregor77324f32008-11-17 14:58:09 +000035 QualType Type;
36
Douglas Gregorae2fbad2008-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 Gregor77324f32008-11-17 14:58:09 +000041 void Profile(llvm::FoldingSetNodeID &ID) {
42 ID.AddInteger(ExtraKindOrNumArgs);
43 ID.AddPointer(Type.getAsOpaquePtr());
44 }
45};
46
Douglas Gregor163c5852008-11-18 14:39:36 +000047/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump11289f42009-09-09 15:08:12 +000048/// overloaded operator in C++, such as "operator+.
Douglas Gregor163c5852008-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 Smithc1b05652012-03-09 08:37:16 +000056/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
Alexis Hunt3d221f22009-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.
Alexis Huntc88db062010-01-13 09:01:02 +000062class CXXLiteralOperatorIdName
63 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Alexis Hunt3d221f22009-11-29 07:34:05 +000064public:
65 IdentifierInfo *ID;
Alexis Huntc88db062010-01-13 09:01:02 +000066
Richard Smithc1b05652012-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
Alexis Huntc88db062010-01-13 09:01:02 +000071 void Profile(llvm::FoldingSetNodeID &FSID) {
72 FSID.AddPointer(ID);
73 }
Alexis Hunt3d221f22009-11-29 07:34:05 +000074};
75
John McCallef3057c2010-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 Gregorb082bab2009-11-04 22:24:30 +000081 if (LHS.getNameKind() != RHS.getNameKind())
John McCallef3057c2010-02-13 01:04:05 +000082 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregorb082bab2009-11-04 22:24:30 +000083
84 switch (LHS.getNameKind()) {
John McCallef3057c2010-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 Gregor77324f32008-11-17 14:58:09 +000093
Douglas Gregorb082bab2009-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 McCallef3057c2010-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 Gregoraf2a6ae2011-02-18 22:29:55 +0000101 switch (LHSSelector.getNameForSlot(I).compare(
102 RHSSelector.getNameForSlot(I))) {
Douglas Gregorb082bab2009-11-04 22:24:30 +0000103 case -1: return true;
104 case 1: return false;
105 default: break;
106 }
107 }
John McCallef3057c2010-02-13 01:04:05 +0000108
109 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +0000110 }
111
112 case DeclarationName::CXXConstructorName:
113 case DeclarationName::CXXDestructorName:
114 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-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 Gregorb082bab2009-11-04 22:24:30 +0000120
121 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000122 return compareInt(LHS.getCXXOverloadedOperator(),
123 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000124
125 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000126 return LHS.getCXXLiteralIdentifier()->getName().compare(
127 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregorb082bab2009-11-04 22:24:30 +0000128
129 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000130 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000131 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000132
133 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000134}
135
136} // end namespace clang
137
Douglas Gregor77324f32008-11-17 14:58:09 +0000138DeclarationName::NameKind DeclarationName::getNameKind() const {
139 switch (getStoredNameKind()) {
140 case StoredIdentifier: return Identifier;
141 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
142 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
143
Douglas Gregor163c5852008-11-18 14:39:36 +0000144 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000145 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000146 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000147 return CXXConstructorName;
148
Mike Stump11289f42009-09-09 15:08:12 +0000149 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000150 return CXXDestructorName;
151
Mike Stump11289f42009-09-09 15:08:12 +0000152 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000153 return CXXConversionFunctionName;
154
Alexis Hunt3d221f22009-11-29 07:34:05 +0000155 case DeclarationNameExtra::CXXLiteralOperator:
156 return CXXLiteralOperatorName;
157
Douglas Gregor889ceb72009-02-03 19:21:40 +0000158 case DeclarationNameExtra::CXXUsingDirective:
159 return CXXUsingDirective;
160
Douglas Gregor77324f32008-11-17 14:58:09 +0000161 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000162 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000163 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000164 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000165 return CXXOperatorName;
166
Douglas Gregor77324f32008-11-17 14:58:09 +0000167 return ObjCMultiArgSelector;
168 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000169 }
170
171 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000172 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000173}
174
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000175bool DeclarationName::isDependentName() const {
176 QualType T = getCXXNameType();
177 return !T.isNull() && T->isDependentType();
178}
179
Douglas Gregor92751d42008-11-17 22:58:34 +0000180std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000181 std::string Result;
182 llvm::raw_string_ostream OS(Result);
183 printName(OS);
184 return OS.str();
185}
186
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000187void DeclarationName::printName(raw_ostream &OS) const {
Douglas Gregor92751d42008-11-17 22:58:34 +0000188 switch (getNameKind()) {
189 case Identifier:
190 if (const IdentifierInfo *II = getAsIdentifierInfo())
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000191 OS << II->getName();
192 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000193
194 case ObjCZeroArgSelector:
195 case ObjCOneArgSelector:
196 case ObjCMultiArgSelector:
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000197 OS << getObjCSelector().getAsString();
198 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000199
200 case CXXConstructorName: {
201 QualType ClassType = getCXXNameType();
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000202 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000203 OS << *ClassRec->getDecl();
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000204 else
205 OS << ClassType.getAsString();
206 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000207 }
208
209 case CXXDestructorName: {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000210 OS << '~';
Douglas Gregor92751d42008-11-17 22:58:34 +0000211 QualType Type = getCXXNameType();
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000212 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000213 OS << *Rec->getDecl();
Douglas Gregor92751d42008-11-17 22:58:34 +0000214 else
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000215 OS << Type.getAsString();
216 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000217 }
218
Douglas Gregor163c5852008-11-18 14:39:36 +0000219 case CXXOperatorName: {
Nuno Lopescfca1f02009-12-23 17:49:57 +0000220 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Douglas Gregor163c5852008-11-18 14:39:36 +0000221 0,
222#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
223 Spelling,
224#include "clang/Basic/OperatorKinds.def"
225 };
226 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
227 assert(OpName && "not an overloaded operator");
Mike Stump11289f42009-09-09 15:08:12 +0000228
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000229 OS << "operator";
Douglas Gregor163c5852008-11-18 14:39:36 +0000230 if (OpName[0] >= 'a' && OpName[0] <= 'z')
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000231 OS << ' ';
232 OS << OpName;
233 return;
Douglas Gregor163c5852008-11-18 14:39:36 +0000234 }
235
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000236 case CXXLiteralOperatorName:
237 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
238 return;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000239
Douglas Gregor92751d42008-11-17 22:58:34 +0000240 case CXXConversionFunctionName: {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000241 OS << "operator ";
Douglas Gregor92751d42008-11-17 22:58:34 +0000242 QualType Type = getCXXNameType();
Ted Kremenekc23c7e62009-07-29 21:53:49 +0000243 if (const RecordType *Rec = Type->getAs<RecordType>())
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000244 OS << *Rec->getDecl();
Douglas Gregor92751d42008-11-17 22:58:34 +0000245 else
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000246 OS << Type.getAsString();
247 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000248 }
Douglas Gregor889ceb72009-02-03 19:21:40 +0000249 case CXXUsingDirective:
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000250 OS << "<using-directive>";
251 return;
Douglas Gregor92751d42008-11-17 22:58:34 +0000252 }
253
David Blaikie83d382b2011-09-23 05:06:16 +0000254 llvm_unreachable("Unexpected declaration name kind");
Douglas Gregor92751d42008-11-17 22:58:34 +0000255}
256
Douglas Gregor77324f32008-11-17 14:58:09 +0000257QualType DeclarationName::getCXXNameType() const {
258 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
259 return CXXName->Type;
260 else
261 return QualType();
262}
263
Douglas Gregor163c5852008-11-18 14:39:36 +0000264OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
265 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000266 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000267 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
268 return static_cast<OverloadedOperatorKind>(value);
269 } else {
270 return OO_None;
271 }
272}
273
Alexis Hunt3d221f22009-11-29 07:34:05 +0000274IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
275 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
276 return CXXLit->ID;
277 else
278 return 0;
279}
280
Douglas Gregor0da53052012-05-03 23:18:44 +0000281void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000282 switch (getNameKind()) {
283 case Identifier:
Douglas Gregor0da53052012-05-03 23:18:44 +0000284 llvm_unreachable("Handled by getFETokenInfoAsVoid()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000285
286 case CXXConstructorName:
287 case CXXDestructorName:
288 case CXXConversionFunctionName:
289 return getAsCXXSpecialName()->FETokenInfo;
290
Douglas Gregor163c5852008-11-18 14:39:36 +0000291 case CXXOperatorName:
292 return getAsCXXOperatorIdName()->FETokenInfo;
293
Alexis Hunt3d221f22009-11-29 07:34:05 +0000294 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000295 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000296
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000297 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000298 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000299 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000300}
301
302void DeclarationName::setFETokenInfo(void *T) {
303 switch (getNameKind()) {
304 case Identifier:
305 getAsIdentifierInfo()->setFETokenInfo(T);
306 break;
307
308 case CXXConstructorName:
309 case CXXDestructorName:
310 case CXXConversionFunctionName:
311 getAsCXXSpecialName()->FETokenInfo = T;
312 break;
313
Douglas Gregor163c5852008-11-18 14:39:36 +0000314 case CXXOperatorName:
315 getAsCXXOperatorIdName()->FETokenInfo = T;
316 break;
317
Alexis Hunt3d221f22009-11-29 07:34:05 +0000318 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000319 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000320 break;
321
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000322 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000323 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000324 }
325}
326
Douglas Gregor889ceb72009-02-03 19:21:40 +0000327DeclarationName DeclarationName::getUsingDirectiveName() {
328 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000329 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000330 { DeclarationNameExtra::CXXUsingDirective };
331
332 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
333 Ptr |= StoredDeclarationNameExtra;
334
335 return DeclarationName(Ptr);
336}
337
Anders Carlsson1b69be22009-11-15 22:30:43 +0000338void DeclarationName::dump() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000339 printName(llvm::errs());
340 llvm::errs() << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000341}
342
Jay Foad39c79802011-01-12 09:06:06 +0000343DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000344 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Alexis Huntc88db062010-01-13 09:01:02 +0000345 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregor163c5852008-11-18 14:39:36 +0000346
347 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000348 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000349 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000350 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000351 = Op + DeclarationNameExtra::CXXConversionFunction;
352 CXXOperatorNames[Op].FETokenInfo = 0;
353 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000354}
355
356DeclarationNameTable::~DeclarationNameTable() {
Alexis Huntc88db062010-01-13 09:01:02 +0000357 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes127adb42008-12-14 17:27:25 +0000358 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Alexis Huntc88db062010-01-13 09:01:02 +0000359 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
360 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000361 (CXXLiteralOperatorNames);
Alexis Huntc88db062010-01-13 09:01:02 +0000362
Alexis Huntc88db062010-01-13 09:01:02 +0000363 delete SpecialNames;
364 delete LiteralNames;
Ted Kremenek6aead3a2010-05-10 20:40:08 +0000365}
366
Mike Stump11289f42009-09-09 15:08:12 +0000367DeclarationName
368DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000369 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000370 assert(Kind >= DeclarationName::CXXConstructorName &&
371 Kind <= DeclarationName::CXXConversionFunctionName &&
372 "Kind must be a C++ special name kind");
Mike Stump11289f42009-09-09 15:08:12 +0000373 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor77324f32008-11-17 14:58:09 +0000374 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
375
376 DeclarationNameExtra::ExtraKind EKind;
377 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000378 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000379 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000380 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000381 break;
382 case DeclarationName::CXXDestructorName:
383 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000384 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000385 break;
386 case DeclarationName::CXXConversionFunctionName:
387 EKind = DeclarationNameExtra::CXXConversionFunction;
388 break;
389 default:
390 return DeclarationName();
391 }
392
393 // Unique selector, to guarantee there is one per name.
394 llvm::FoldingSetNodeID ID;
395 ID.AddInteger(EKind);
396 ID.AddPointer(Ty.getAsOpaquePtr());
397
398 void *InsertPos = 0;
399 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
400 return DeclarationName(Name);
401
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000402 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000403 SpecialName->ExtraKindOrNumArgs = EKind;
404 SpecialName->Type = Ty;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000405 SpecialName->FETokenInfo = 0;
Douglas Gregor77324f32008-11-17 14:58:09 +0000406
407 SpecialNames->InsertNode(SpecialName, InsertPos);
408 return DeclarationName(SpecialName);
409}
410
Mike Stump11289f42009-09-09 15:08:12 +0000411DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000412DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
413 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
414}
415
Alexis Hunt3d221f22009-11-29 07:34:05 +0000416DeclarationName
417DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000418 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
419 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
420 (CXXLiteralOperatorNames);
421
422 llvm::FoldingSetNodeID ID;
423 ID.AddPointer(II);
424
425 void *InsertPos = 0;
426 if (CXXLiteralOperatorIdName *Name =
427 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
428 return DeclarationName (Name);
429
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000430 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000431 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
432 LiteralName->ID = II;
Richard Smithc1b05652012-03-09 08:37:16 +0000433 LiteralName->FETokenInfo = 0;
Alexis Huntc88db062010-01-13 09:01:02 +0000434
435 LiteralNames->InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000436 return DeclarationName(LiteralName);
437}
438
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000439DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
440 switch (Name.getNameKind()) {
441 case DeclarationName::Identifier:
442 break;
443 case DeclarationName::CXXConstructorName:
444 case DeclarationName::CXXDestructorName:
445 case DeclarationName::CXXConversionFunctionName:
446 NamedType.TInfo = 0;
447 break;
448 case DeclarationName::CXXOperatorName:
449 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
450 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
451 break;
452 case DeclarationName::CXXLiteralOperatorName:
453 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
454 break;
455 case DeclarationName::ObjCZeroArgSelector:
456 case DeclarationName::ObjCOneArgSelector:
457 case DeclarationName::ObjCMultiArgSelector:
458 // FIXME: ?
459 break;
460 case DeclarationName::CXXUsingDirective:
461 break;
462 }
463}
464
Douglas Gregora6e053e2010-12-15 01:34:56 +0000465bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
466 switch (Name.getNameKind()) {
467 case DeclarationName::Identifier:
468 case DeclarationName::ObjCZeroArgSelector:
469 case DeclarationName::ObjCOneArgSelector:
470 case DeclarationName::ObjCMultiArgSelector:
471 case DeclarationName::CXXOperatorName:
472 case DeclarationName::CXXLiteralOperatorName:
473 case DeclarationName::CXXUsingDirective:
474 return false;
475
476 case DeclarationName::CXXConstructorName:
477 case DeclarationName::CXXDestructorName:
478 case DeclarationName::CXXConversionFunctionName:
479 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
480 return TInfo->getType()->containsUnexpandedParameterPack();
481
482 return Name.getCXXNameType()->containsUnexpandedParameterPack();
483 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000484 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000485}
486
Douglas Gregor678d76c2011-07-01 01:22:09 +0000487bool DeclarationNameInfo::isInstantiationDependent() const {
488 switch (Name.getNameKind()) {
489 case DeclarationName::Identifier:
490 case DeclarationName::ObjCZeroArgSelector:
491 case DeclarationName::ObjCOneArgSelector:
492 case DeclarationName::ObjCMultiArgSelector:
493 case DeclarationName::CXXOperatorName:
494 case DeclarationName::CXXLiteralOperatorName:
495 case DeclarationName::CXXUsingDirective:
496 return false;
497
498 case DeclarationName::CXXConstructorName:
499 case DeclarationName::CXXDestructorName:
500 case DeclarationName::CXXConversionFunctionName:
501 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
502 return TInfo->getType()->isInstantiationDependentType();
503
504 return Name.getCXXNameType()->isInstantiationDependentType();
505 }
506 llvm_unreachable("All name kinds handled.");
507}
508
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000509std::string DeclarationNameInfo::getAsString() const {
510 std::string Result;
511 llvm::raw_string_ostream OS(Result);
512 printName(OS);
513 return OS.str();
514}
515
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000516void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000517 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 Name.printName(OS);
526 return;
527
528 case DeclarationName::CXXConstructorName:
529 case DeclarationName::CXXDestructorName:
530 case DeclarationName::CXXConversionFunctionName:
531 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
532 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
533 OS << '~';
534 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
535 OS << "operator ";
536 OS << TInfo->getType().getAsString();
537 }
538 else
539 Name.printName(OS);
540 return;
541 }
David Blaikie83d382b2011-09-23 05:06:16 +0000542 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000543}
544
545SourceLocation DeclarationNameInfo::getEndLoc() const {
546 switch (Name.getNameKind()) {
547 case DeclarationName::Identifier:
548 return NameLoc;
549
550 case DeclarationName::CXXOperatorName: {
551 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
552 return SourceLocation::getFromRawEncoding(raw);
553 }
554
555 case DeclarationName::CXXLiteralOperatorName: {
556 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
557 return SourceLocation::getFromRawEncoding(raw);
558 }
559
560 case DeclarationName::CXXConstructorName:
561 case DeclarationName::CXXDestructorName:
562 case DeclarationName::CXXConversionFunctionName:
563 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
564 return TInfo->getTypeLoc().getEndLoc();
565 else
566 return NameLoc;
567
568 // DNInfo work in progress: FIXME.
569 case DeclarationName::ObjCZeroArgSelector:
570 case DeclarationName::ObjCOneArgSelector:
571 case DeclarationName::ObjCMultiArgSelector:
572 case DeclarationName::CXXUsingDirective:
573 return NameLoc;
574 }
David Blaikie83d382b2011-09-23 05:06:16 +0000575 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000576}