blob: 2a988e1d22d03efb452a87306d98198009eca523 [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"
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +000015#include "clang/AST/DeclCXX.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
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000136static void printCXXConstructorDestructorName(QualType ClassType,
137 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000138 PrintingPolicy Policy) {
139 // We know we're printing C++ here. Ensure we print types properly.
140 Policy.adjustForCPlusPlus();
141
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000142 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
143 OS << *ClassRec->getDecl();
144 return;
145 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000146 if (Policy.SuppressTemplateArgsInCXXConstructors) {
147 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
148 OS << *InjTy->getDecl();
149 return;
150 }
151 }
Richard Smith301bc212016-05-19 01:39:10 +0000152 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000153}
154
155void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
156 DeclarationName &N = *this;
David Blaikied4da8722013-05-14 21:04:00 +0000157 switch (N.getNameKind()) {
158 case DeclarationName::Identifier:
159 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
160 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000161 return;
David Blaikied4da8722013-05-14 21:04:00 +0000162
163 case DeclarationName::ObjCZeroArgSelector:
164 case DeclarationName::ObjCOneArgSelector:
165 case DeclarationName::ObjCMultiArgSelector:
Aaron Ballmanb190f972014-01-03 17:59:55 +0000166 N.getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000167 return;
David Blaikied4da8722013-05-14 21:04:00 +0000168
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000169 case DeclarationName::CXXConstructorName:
170 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000171
172 case DeclarationName::CXXDestructorName: {
173 OS << '~';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000174 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000175 }
176
177 case DeclarationName::CXXOperatorName: {
178 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Craig Topper36250ad2014-05-12 05:36:57 +0000179 nullptr,
David Blaikied4da8722013-05-14 21:04:00 +0000180#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
181 Spelling,
182#include "clang/Basic/OperatorKinds.def"
183 };
184 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
185 assert(OpName && "not an overloaded operator");
186
187 OS << "operator";
188 if (OpName[0] >= 'a' && OpName[0] <= 'z')
189 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000190 OS << OpName;
191 return;
David Blaikied4da8722013-05-14 21:04:00 +0000192 }
193
194 case DeclarationName::CXXLiteralOperatorName:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000195 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
196 return;
David Blaikied4da8722013-05-14 21:04:00 +0000197
198 case DeclarationName::CXXConversionFunctionName: {
199 OS << "operator ";
200 QualType Type = N.getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000201 if (const RecordType *Rec = Type->getAs<RecordType>()) {
202 OS << *Rec->getDecl();
203 return;
204 }
Richard Smith301bc212016-05-19 01:39:10 +0000205 // We know we're printing C++ here, ensure we print 'bool' properly.
206 PrintingPolicy CXXPolicy = Policy;
207 CXXPolicy.adjustForCPlusPlus();
208 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000209 return;
David Blaikied4da8722013-05-14 21:04:00 +0000210 }
211 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000212 OS << "<using-directive>";
213 return;
David Blaikied4da8722013-05-14 21:04:00 +0000214 }
215
216 llvm_unreachable("Unexpected declaration name kind");
217}
218
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000219raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
220 LangOptions LO;
221 N.print(OS, PrintingPolicy(LO));
222 return OS;
223}
224
Douglas Gregor77324f32008-11-17 14:58:09 +0000225} // end namespace clang
226
Douglas Gregor77324f32008-11-17 14:58:09 +0000227DeclarationName::NameKind DeclarationName::getNameKind() const {
228 switch (getStoredNameKind()) {
229 case StoredIdentifier: return Identifier;
230 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
231 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
232
Douglas Gregor163c5852008-11-18 14:39:36 +0000233 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000234 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000235 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000236 return CXXConstructorName;
237
Mike Stump11289f42009-09-09 15:08:12 +0000238 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000239 return CXXDestructorName;
240
Mike Stump11289f42009-09-09 15:08:12 +0000241 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000242 return CXXConversionFunctionName;
243
Alexis Hunt3d221f22009-11-29 07:34:05 +0000244 case DeclarationNameExtra::CXXLiteralOperator:
245 return CXXLiteralOperatorName;
246
Douglas Gregor889ceb72009-02-03 19:21:40 +0000247 case DeclarationNameExtra::CXXUsingDirective:
248 return CXXUsingDirective;
249
Douglas Gregor77324f32008-11-17 14:58:09 +0000250 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000251 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000252 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000253 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000254 return CXXOperatorName;
255
Douglas Gregor77324f32008-11-17 14:58:09 +0000256 return ObjCMultiArgSelector;
257 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000258 }
259
260 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000261 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000262}
263
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000264bool DeclarationName::isDependentName() const {
265 QualType T = getCXXNameType();
266 return !T.isNull() && T->isDependentType();
267}
268
Douglas Gregor92751d42008-11-17 22:58:34 +0000269std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000270 std::string Result;
271 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000272 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000273 return OS.str();
274}
275
Douglas Gregor77324f32008-11-17 14:58:09 +0000276QualType DeclarationName::getCXXNameType() const {
277 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
278 return CXXName->Type;
279 else
280 return QualType();
281}
282
Douglas Gregor163c5852008-11-18 14:39:36 +0000283OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
284 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000285 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000286 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
287 return static_cast<OverloadedOperatorKind>(value);
288 } else {
289 return OO_None;
290 }
291}
292
Alexis Hunt3d221f22009-11-29 07:34:05 +0000293IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
294 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
295 return CXXLit->ID;
296 else
Craig Topper36250ad2014-05-12 05:36:57 +0000297 return nullptr;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000298}
299
Douglas Gregor0da53052012-05-03 23:18:44 +0000300void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000301 switch (getNameKind()) {
302 case Identifier:
Benjamin Kramer1458c1c2012-05-19 16:03:58 +0000303 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000304
305 case CXXConstructorName:
306 case CXXDestructorName:
307 case CXXConversionFunctionName:
308 return getAsCXXSpecialName()->FETokenInfo;
309
Douglas Gregor163c5852008-11-18 14:39:36 +0000310 case CXXOperatorName:
311 return getAsCXXOperatorIdName()->FETokenInfo;
312
Alexis Hunt3d221f22009-11-29 07:34:05 +0000313 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000314 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000315
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000316 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000317 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000318 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000319}
320
321void DeclarationName::setFETokenInfo(void *T) {
322 switch (getNameKind()) {
323 case Identifier:
324 getAsIdentifierInfo()->setFETokenInfo(T);
325 break;
326
327 case CXXConstructorName:
328 case CXXDestructorName:
329 case CXXConversionFunctionName:
330 getAsCXXSpecialName()->FETokenInfo = T;
331 break;
332
Douglas Gregor163c5852008-11-18 14:39:36 +0000333 case CXXOperatorName:
334 getAsCXXOperatorIdName()->FETokenInfo = T;
335 break;
336
Alexis Hunt3d221f22009-11-29 07:34:05 +0000337 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000338 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000339 break;
340
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000341 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000342 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000343 }
344}
345
Douglas Gregor889ceb72009-02-03 19:21:40 +0000346DeclarationName DeclarationName::getUsingDirectiveName() {
347 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000348 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000349 { DeclarationNameExtra::CXXUsingDirective };
350
351 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
352 Ptr |= StoredDeclarationNameExtra;
353
354 return DeclarationName(Ptr);
355}
356
Yaron Kerencdae9412016-01-29 19:38:18 +0000357LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000358 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000359}
360
Jay Foad39c79802011-01-12 09:06:06 +0000361DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000362 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Alexis Huntc88db062010-01-13 09:01:02 +0000363 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregor163c5852008-11-18 14:39:36 +0000364
365 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000366 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000367 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000368 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000369 = Op + DeclarationNameExtra::CXXConversionFunction;
Craig Topper36250ad2014-05-12 05:36:57 +0000370 CXXOperatorNames[Op].FETokenInfo = nullptr;
Douglas Gregor163c5852008-11-18 14:39:36 +0000371 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000372}
373
374DeclarationNameTable::~DeclarationNameTable() {
Alexis Huntc88db062010-01-13 09:01:02 +0000375 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes127adb42008-12-14 17:27:25 +0000376 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Alexis Huntc88db062010-01-13 09:01:02 +0000377 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
378 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000379 (CXXLiteralOperatorNames);
Alexis Huntc88db062010-01-13 09:01:02 +0000380
Alexis Huntc88db062010-01-13 09:01:02 +0000381 delete SpecialNames;
382 delete LiteralNames;
Ted Kremenek6aead3a2010-05-10 20:40:08 +0000383}
384
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000385DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
386 return getCXXSpecialName(DeclarationName::CXXConstructorName,
387 Ty.getUnqualifiedType());
388}
389
390DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
391 return getCXXSpecialName(DeclarationName::CXXDestructorName,
392 Ty.getUnqualifiedType());
393}
394
395DeclarationName
396DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
397 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
398}
399
Mike Stump11289f42009-09-09 15:08:12 +0000400DeclarationName
401DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000402 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000403 assert(Kind >= DeclarationName::CXXConstructorName &&
404 Kind <= DeclarationName::CXXConversionFunctionName &&
405 "Kind must be a C++ special name kind");
Mike Stump11289f42009-09-09 15:08:12 +0000406 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor77324f32008-11-17 14:58:09 +0000407 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
408
409 DeclarationNameExtra::ExtraKind EKind;
410 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000411 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000412 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000413 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000414 break;
415 case DeclarationName::CXXDestructorName:
416 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000417 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000418 break;
419 case DeclarationName::CXXConversionFunctionName:
420 EKind = DeclarationNameExtra::CXXConversionFunction;
421 break;
422 default:
423 return DeclarationName();
424 }
425
426 // Unique selector, to guarantee there is one per name.
427 llvm::FoldingSetNodeID ID;
428 ID.AddInteger(EKind);
429 ID.AddPointer(Ty.getAsOpaquePtr());
430
Craig Topper36250ad2014-05-12 05:36:57 +0000431 void *InsertPos = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000432 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
433 return DeclarationName(Name);
434
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000435 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000436 SpecialName->ExtraKindOrNumArgs = EKind;
437 SpecialName->Type = Ty;
Craig Topper36250ad2014-05-12 05:36:57 +0000438 SpecialName->FETokenInfo = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000439
440 SpecialNames->InsertNode(SpecialName, InsertPos);
441 return DeclarationName(SpecialName);
442}
443
Mike Stump11289f42009-09-09 15:08:12 +0000444DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000445DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
446 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
447}
448
Alexis Hunt3d221f22009-11-29 07:34:05 +0000449DeclarationName
450DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000451 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
452 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
453 (CXXLiteralOperatorNames);
454
455 llvm::FoldingSetNodeID ID;
456 ID.AddPointer(II);
457
Craig Topper36250ad2014-05-12 05:36:57 +0000458 void *InsertPos = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000459 if (CXXLiteralOperatorIdName *Name =
460 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
461 return DeclarationName (Name);
462
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000463 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000464 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
465 LiteralName->ID = II;
Craig Topper36250ad2014-05-12 05:36:57 +0000466 LiteralName->FETokenInfo = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000467
468 LiteralNames->InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000469 return DeclarationName(LiteralName);
470}
471
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000472DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
473 switch (Name.getNameKind()) {
474 case DeclarationName::Identifier:
475 break;
476 case DeclarationName::CXXConstructorName:
477 case DeclarationName::CXXDestructorName:
478 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000479 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000480 break;
481 case DeclarationName::CXXOperatorName:
482 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
483 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
484 break;
485 case DeclarationName::CXXLiteralOperatorName:
486 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
487 break;
488 case DeclarationName::ObjCZeroArgSelector:
489 case DeclarationName::ObjCOneArgSelector:
490 case DeclarationName::ObjCMultiArgSelector:
491 // FIXME: ?
492 break;
493 case DeclarationName::CXXUsingDirective:
494 break;
495 }
496}
497
Douglas Gregora6e053e2010-12-15 01:34:56 +0000498bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
499 switch (Name.getNameKind()) {
500 case DeclarationName::Identifier:
501 case DeclarationName::ObjCZeroArgSelector:
502 case DeclarationName::ObjCOneArgSelector:
503 case DeclarationName::ObjCMultiArgSelector:
504 case DeclarationName::CXXOperatorName:
505 case DeclarationName::CXXLiteralOperatorName:
506 case DeclarationName::CXXUsingDirective:
507 return false;
508
509 case DeclarationName::CXXConstructorName:
510 case DeclarationName::CXXDestructorName:
511 case DeclarationName::CXXConversionFunctionName:
512 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
513 return TInfo->getType()->containsUnexpandedParameterPack();
514
515 return Name.getCXXNameType()->containsUnexpandedParameterPack();
516 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000517 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000518}
519
Douglas Gregor678d76c2011-07-01 01:22:09 +0000520bool DeclarationNameInfo::isInstantiationDependent() const {
521 switch (Name.getNameKind()) {
522 case DeclarationName::Identifier:
523 case DeclarationName::ObjCZeroArgSelector:
524 case DeclarationName::ObjCOneArgSelector:
525 case DeclarationName::ObjCMultiArgSelector:
526 case DeclarationName::CXXOperatorName:
527 case DeclarationName::CXXLiteralOperatorName:
528 case DeclarationName::CXXUsingDirective:
529 return false;
530
531 case DeclarationName::CXXConstructorName:
532 case DeclarationName::CXXDestructorName:
533 case DeclarationName::CXXConversionFunctionName:
534 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
535 return TInfo->getType()->isInstantiationDependentType();
536
537 return Name.getCXXNameType()->isInstantiationDependentType();
538 }
539 llvm_unreachable("All name kinds handled.");
540}
541
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000542std::string DeclarationNameInfo::getAsString() const {
543 std::string Result;
544 llvm::raw_string_ostream OS(Result);
545 printName(OS);
546 return OS.str();
547}
548
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000549void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000550 switch (Name.getNameKind()) {
551 case DeclarationName::Identifier:
552 case DeclarationName::ObjCZeroArgSelector:
553 case DeclarationName::ObjCOneArgSelector:
554 case DeclarationName::ObjCMultiArgSelector:
555 case DeclarationName::CXXOperatorName:
556 case DeclarationName::CXXLiteralOperatorName:
557 case DeclarationName::CXXUsingDirective:
David Blaikied4da8722013-05-14 21:04:00 +0000558 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000559 return;
560
561 case DeclarationName::CXXConstructorName:
562 case DeclarationName::CXXDestructorName:
563 case DeclarationName::CXXConversionFunctionName:
564 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
565 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
566 OS << '~';
567 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
568 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000569 LangOptions LO;
570 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000571 LO.Bool = true;
Richard Smithe81daee2014-01-22 00:27:42 +0000572 OS << TInfo->getType().getAsString(PrintingPolicy(LO));
David Blaikied4da8722013-05-14 21:04:00 +0000573 } else
574 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000575 return;
576 }
David Blaikie83d382b2011-09-23 05:06:16 +0000577 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000578}
579
580SourceLocation DeclarationNameInfo::getEndLoc() const {
581 switch (Name.getNameKind()) {
582 case DeclarationName::Identifier:
583 return NameLoc;
584
585 case DeclarationName::CXXOperatorName: {
586 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
587 return SourceLocation::getFromRawEncoding(raw);
588 }
589
590 case DeclarationName::CXXLiteralOperatorName: {
591 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
592 return SourceLocation::getFromRawEncoding(raw);
593 }
594
595 case DeclarationName::CXXConstructorName:
596 case DeclarationName::CXXDestructorName:
597 case DeclarationName::CXXConversionFunctionName:
598 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
599 return TInfo->getTypeLoc().getEndLoc();
600 else
601 return NameLoc;
602
603 // DNInfo work in progress: FIXME.
604 case DeclarationName::ObjCZeroArgSelector:
605 case DeclarationName::ObjCOneArgSelector:
606 case DeclarationName::ObjCMultiArgSelector:
607 case DeclarationName::CXXUsingDirective:
608 return NameLoc;
609 }
David Blaikie83d382b2011-09-23 05:06:16 +0000610 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000611}