blob: 1f8e26deda9790295bd3bd0f3e339cdff2205114 [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//===----------------------------------------------------------------------===//
Mehdi Amini9670f842016-07-18 19:02:11 +000014#include "clang/AST/DeclarationName.h"
Ted Kremenek6aead3a2010-05-10 20:40:08 +000015#include "clang/AST/ASTContext.h"
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +000016#include "clang/AST/DeclCXX.h"
Richard Smith35845152017-02-07 01:37:30 +000017#include "clang/AST/DeclTemplate.h"
Douglas Gregor92751d42008-11-17 22:58:34 +000018#include "clang/AST/Type.h"
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000019#include "clang/AST/TypeLoc.h"
Douglas Gregorb082bab2009-11-04 22:24:30 +000020#include "clang/AST/TypeOrdering.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000021#include "clang/Basic/IdentifierTable.h"
22#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
Richard Smith35845152017-02-07 01:37:30 +000047/// Contains extra information for the name of a C++ deduction guide.
48class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
49 public llvm::FoldingSetNode {
50public:
51 /// The template named by the deduction guide.
52 TemplateDecl *Template;
53
54 /// FETokenInfo - Extra information associated with this operator
55 /// name that can be used by the front end.
56 void *FETokenInfo;
57
58 void Profile(llvm::FoldingSetNodeID &ID) {
59 ID.AddPointer(Template);
60 }
61};
62
Douglas Gregor163c5852008-11-18 14:39:36 +000063/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump11289f42009-09-09 15:08:12 +000064/// overloaded operator in C++, such as "operator+.
Douglas Gregor163c5852008-11-18 14:39:36 +000065class CXXOperatorIdName : public DeclarationNameExtra {
66public:
67 /// FETokenInfo - Extra information associated with this operator
68 /// name that can be used by the front end.
69 void *FETokenInfo;
70};
71
Richard Smithc1b05652012-03-09 08:37:16 +000072/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
Alexis Hunt3d221f22009-11-29 07:34:05 +000073/// name.
74///
75/// This identifier is stored here rather than directly in DeclarationName so as
76/// to allow Objective-C selectors, which are about a million times more common,
77/// to consume minimal memory.
Alexis Huntc88db062010-01-13 09:01:02 +000078class CXXLiteralOperatorIdName
79 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Alexis Hunt3d221f22009-11-29 07:34:05 +000080public:
81 IdentifierInfo *ID;
Alexis Huntc88db062010-01-13 09:01:02 +000082
Richard Smithc1b05652012-03-09 08:37:16 +000083 /// FETokenInfo - Extra information associated with this operator
84 /// name that can be used by the front end.
85 void *FETokenInfo;
86
Alexis Huntc88db062010-01-13 09:01:02 +000087 void Profile(llvm::FoldingSetNodeID &FSID) {
88 FSID.AddPointer(ID);
89 }
Alexis Hunt3d221f22009-11-29 07:34:05 +000090};
91
John McCallef3057c2010-02-13 01:04:05 +000092static int compareInt(unsigned A, unsigned B) {
93 return (A < B ? -1 : (A > B ? 1 : 0));
94}
95
96int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregorb082bab2009-11-04 22:24:30 +000097 if (LHS.getNameKind() != RHS.getNameKind())
John McCallef3057c2010-02-13 01:04:05 +000098 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregorb082bab2009-11-04 22:24:30 +000099
100 switch (LHS.getNameKind()) {
John McCallef3057c2010-02-13 01:04:05 +0000101 case DeclarationName::Identifier: {
102 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
103 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
104 if (!LII) return RII ? -1 : 0;
105 if (!RII) return 1;
106
107 return LII->getName().compare(RII->getName());
108 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000109
Douglas Gregorb082bab2009-11-04 22:24:30 +0000110 case DeclarationName::ObjCZeroArgSelector:
111 case DeclarationName::ObjCOneArgSelector:
112 case DeclarationName::ObjCMultiArgSelector: {
113 Selector LHSSelector = LHS.getObjCSelector();
114 Selector RHSSelector = RHS.getObjCSelector();
Manman Renb6665732016-11-17 18:41:18 +0000115 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
116 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
117 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
118 return LHSSelector.getAsIdentifierInfo()->getName().compare(
119 RHSSelector.getAsIdentifierInfo()->getName());
120 }
John McCallef3057c2010-02-13 01:04:05 +0000121 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
122 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +0000123 switch (LHSSelector.getNameForSlot(I).compare(
124 RHSSelector.getNameForSlot(I))) {
Manman Renb6665732016-11-17 18:41:18 +0000125 case -1: return -1;
126 case 1: return 1;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000127 default: break;
128 }
129 }
John McCallef3057c2010-02-13 01:04:05 +0000130
131 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +0000132 }
133
134 case DeclarationName::CXXConstructorName:
135 case DeclarationName::CXXDestructorName:
136 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +0000137 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
138 return -1;
139 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
140 return 1;
141 return 0;
Richard Smith35845152017-02-07 01:37:30 +0000142
143 case DeclarationName::CXXDeductionGuideName:
144 // We never want to compare deduction guide names for templates from
145 // different scopes, so just compare the template-name.
146 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
147 RHS.getCXXDeductionGuideTemplate()->getDeclName());
148
Douglas Gregorb082bab2009-11-04 22:24:30 +0000149 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000150 return compareInt(LHS.getCXXOverloadedOperator(),
151 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000152
153 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000154 return LHS.getCXXLiteralIdentifier()->getName().compare(
155 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregorb082bab2009-11-04 22:24:30 +0000156
157 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000158 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000159 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000160
161 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000162}
163
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000164static void printCXXConstructorDestructorName(QualType ClassType,
165 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000166 PrintingPolicy Policy) {
167 // We know we're printing C++ here. Ensure we print types properly.
168 Policy.adjustForCPlusPlus();
169
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000170 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
171 OS << *ClassRec->getDecl();
172 return;
173 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000174 if (Policy.SuppressTemplateArgsInCXXConstructors) {
175 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
176 OS << *InjTy->getDecl();
177 return;
178 }
179 }
Richard Smith301bc212016-05-19 01:39:10 +0000180 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000181}
182
183void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
184 DeclarationName &N = *this;
David Blaikied4da8722013-05-14 21:04:00 +0000185 switch (N.getNameKind()) {
186 case DeclarationName::Identifier:
187 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
188 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000189 return;
David Blaikied4da8722013-05-14 21:04:00 +0000190
191 case DeclarationName::ObjCZeroArgSelector:
192 case DeclarationName::ObjCOneArgSelector:
193 case DeclarationName::ObjCMultiArgSelector:
Aaron Ballmanb190f972014-01-03 17:59:55 +0000194 N.getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000195 return;
David Blaikied4da8722013-05-14 21:04:00 +0000196
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000197 case DeclarationName::CXXConstructorName:
198 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000199
200 case DeclarationName::CXXDestructorName: {
201 OS << '~';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000202 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000203 }
204
Richard Smith35845152017-02-07 01:37:30 +0000205 case DeclarationName::CXXDeductionGuideName:
Richard Smithf283fdc2017-02-08 00:35:25 +0000206 OS << "<deduction guide for ";
207 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
208 OS << '>';
209 return;
Richard Smith35845152017-02-07 01:37:30 +0000210
David Blaikied4da8722013-05-14 21:04:00 +0000211 case DeclarationName::CXXOperatorName: {
212 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Craig Topper36250ad2014-05-12 05:36:57 +0000213 nullptr,
David Blaikied4da8722013-05-14 21:04:00 +0000214#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
215 Spelling,
216#include "clang/Basic/OperatorKinds.def"
217 };
218 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
219 assert(OpName && "not an overloaded operator");
220
221 OS << "operator";
222 if (OpName[0] >= 'a' && OpName[0] <= 'z')
223 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000224 OS << OpName;
225 return;
David Blaikied4da8722013-05-14 21:04:00 +0000226 }
227
228 case DeclarationName::CXXLiteralOperatorName:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000229 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
230 return;
David Blaikied4da8722013-05-14 21:04:00 +0000231
232 case DeclarationName::CXXConversionFunctionName: {
233 OS << "operator ";
234 QualType Type = N.getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000235 if (const RecordType *Rec = Type->getAs<RecordType>()) {
236 OS << *Rec->getDecl();
237 return;
238 }
Richard Smith301bc212016-05-19 01:39:10 +0000239 // We know we're printing C++ here, ensure we print 'bool' properly.
240 PrintingPolicy CXXPolicy = Policy;
241 CXXPolicy.adjustForCPlusPlus();
242 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000243 return;
David Blaikied4da8722013-05-14 21:04:00 +0000244 }
245 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000246 OS << "<using-directive>";
247 return;
David Blaikied4da8722013-05-14 21:04:00 +0000248 }
249
250 llvm_unreachable("Unexpected declaration name kind");
251}
252
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000253raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
254 LangOptions LO;
255 N.print(OS, PrintingPolicy(LO));
256 return OS;
257}
258
Douglas Gregor77324f32008-11-17 14:58:09 +0000259} // end namespace clang
260
Douglas Gregor77324f32008-11-17 14:58:09 +0000261DeclarationName::NameKind DeclarationName::getNameKind() const {
262 switch (getStoredNameKind()) {
263 case StoredIdentifier: return Identifier;
264 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
265 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
266
Douglas Gregor163c5852008-11-18 14:39:36 +0000267 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000268 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000269 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000270 return CXXConstructorName;
271
Mike Stump11289f42009-09-09 15:08:12 +0000272 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000273 return CXXDestructorName;
274
Richard Smith35845152017-02-07 01:37:30 +0000275 case DeclarationNameExtra::CXXDeductionGuide:
276 return CXXDeductionGuideName;
277
Mike Stump11289f42009-09-09 15:08:12 +0000278 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000279 return CXXConversionFunctionName;
280
Alexis Hunt3d221f22009-11-29 07:34:05 +0000281 case DeclarationNameExtra::CXXLiteralOperator:
282 return CXXLiteralOperatorName;
283
Douglas Gregor889ceb72009-02-03 19:21:40 +0000284 case DeclarationNameExtra::CXXUsingDirective:
285 return CXXUsingDirective;
286
Douglas Gregor77324f32008-11-17 14:58:09 +0000287 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000288 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000289 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000290 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000291 return CXXOperatorName;
292
Douglas Gregor77324f32008-11-17 14:58:09 +0000293 return ObjCMultiArgSelector;
294 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000295 }
296
297 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000298 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000299}
300
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000301bool DeclarationName::isDependentName() const {
302 QualType T = getCXXNameType();
Richard Smith35845152017-02-07 01:37:30 +0000303 if (!T.isNull() && T->isDependentType())
304 return true;
305
306 // A class-scope deduction guide in a dependent context has a dependent name.
307 auto *TD = getCXXDeductionGuideTemplate();
308 if (TD && TD->getDeclContext()->isDependentContext())
309 return true;
310
311 return false;
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000312}
313
Douglas Gregor92751d42008-11-17 22:58:34 +0000314std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000315 std::string Result;
316 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000317 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000318 return OS.str();
319}
320
Douglas Gregor77324f32008-11-17 14:58:09 +0000321QualType DeclarationName::getCXXNameType() const {
322 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
323 return CXXName->Type;
324 else
325 return QualType();
326}
327
Richard Smith35845152017-02-07 01:37:30 +0000328TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const {
329 if (auto *Guide = getAsCXXDeductionGuideNameExtra())
330 return Guide->Template;
331 return nullptr;
332}
333
Douglas Gregor163c5852008-11-18 14:39:36 +0000334OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
335 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000336 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000337 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
338 return static_cast<OverloadedOperatorKind>(value);
339 } else {
340 return OO_None;
341 }
342}
343
Alexis Hunt3d221f22009-11-29 07:34:05 +0000344IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
345 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
346 return CXXLit->ID;
347 else
Craig Topper36250ad2014-05-12 05:36:57 +0000348 return nullptr;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000349}
350
Douglas Gregor0da53052012-05-03 23:18:44 +0000351void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000352 switch (getNameKind()) {
353 case Identifier:
Benjamin Kramer1458c1c2012-05-19 16:03:58 +0000354 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000355
356 case CXXConstructorName:
357 case CXXDestructorName:
358 case CXXConversionFunctionName:
359 return getAsCXXSpecialName()->FETokenInfo;
360
Richard Smith35845152017-02-07 01:37:30 +0000361 case CXXDeductionGuideName:
362 return getAsCXXDeductionGuideNameExtra()->FETokenInfo;
363
Douglas Gregor163c5852008-11-18 14:39:36 +0000364 case CXXOperatorName:
365 return getAsCXXOperatorIdName()->FETokenInfo;
366
Alexis Hunt3d221f22009-11-29 07:34:05 +0000367 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000368 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000369
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000370 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000371 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000372 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000373}
374
375void DeclarationName::setFETokenInfo(void *T) {
376 switch (getNameKind()) {
377 case Identifier:
378 getAsIdentifierInfo()->setFETokenInfo(T);
379 break;
380
381 case CXXConstructorName:
382 case CXXDestructorName:
383 case CXXConversionFunctionName:
384 getAsCXXSpecialName()->FETokenInfo = T;
385 break;
386
Richard Smith35845152017-02-07 01:37:30 +0000387 case CXXDeductionGuideName:
388 getAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
389 break;
390
Douglas Gregor163c5852008-11-18 14:39:36 +0000391 case CXXOperatorName:
392 getAsCXXOperatorIdName()->FETokenInfo = T;
393 break;
394
Alexis Hunt3d221f22009-11-29 07:34:05 +0000395 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000396 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000397 break;
398
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000399 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000400 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000401 }
402}
403
Douglas Gregor889ceb72009-02-03 19:21:40 +0000404DeclarationName DeclarationName::getUsingDirectiveName() {
405 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000406 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000407 { DeclarationNameExtra::CXXUsingDirective };
408
409 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
410 Ptr |= StoredDeclarationNameExtra;
411
412 return DeclarationName(Ptr);
413}
414
Yaron Kerencdae9412016-01-29 19:38:18 +0000415LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000416 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000417}
418
Jay Foad39c79802011-01-12 09:06:06 +0000419DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000420 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Alexis Huntc88db062010-01-13 09:01:02 +0000421 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Richard Smith35845152017-02-07 01:37:30 +0000422 CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>;
Douglas Gregor163c5852008-11-18 14:39:36 +0000423
424 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000425 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000426 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000427 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000428 = Op + DeclarationNameExtra::CXXConversionFunction;
Craig Topper36250ad2014-05-12 05:36:57 +0000429 CXXOperatorNames[Op].FETokenInfo = nullptr;
Douglas Gregor163c5852008-11-18 14:39:36 +0000430 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000431}
432
433DeclarationNameTable::~DeclarationNameTable() {
Richard Smith35845152017-02-07 01:37:30 +0000434 auto *SpecialNames =
435 static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl);
436 auto *LiteralNames =
437 static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>(
438 CXXLiteralOperatorNames);
439 auto *DeductionGuideNames =
440 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
441 CXXDeductionGuideNames);
Alexis Huntc88db062010-01-13 09:01:02 +0000442
Alexis Huntc88db062010-01-13 09:01:02 +0000443 delete SpecialNames;
444 delete LiteralNames;
Richard Smith35845152017-02-07 01:37:30 +0000445 delete DeductionGuideNames;
Ted Kremenek6aead3a2010-05-10 20:40:08 +0000446}
447
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000448DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
449 return getCXXSpecialName(DeclarationName::CXXConstructorName,
450 Ty.getUnqualifiedType());
451}
452
453DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
454 return getCXXSpecialName(DeclarationName::CXXDestructorName,
455 Ty.getUnqualifiedType());
456}
457
458DeclarationName
Richard Smith35845152017-02-07 01:37:30 +0000459DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
460 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
461
462 auto *DeductionGuideNames =
463 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
464 CXXDeductionGuideNames);
465
466 llvm::FoldingSetNodeID ID;
467 ID.AddPointer(Template);
468
469 void *InsertPos = nullptr;
470 if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos))
471 return DeclarationName(Name);
472
473 auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
474 Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
475 Name->Template = Template;
476 Name->FETokenInfo = nullptr;
477
478 DeductionGuideNames->InsertNode(Name, InsertPos);
479 return DeclarationName(Name);
480}
481
482DeclarationName
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000483DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
484 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
485}
486
Mike Stump11289f42009-09-09 15:08:12 +0000487DeclarationName
488DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000489 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000490 assert(Kind >= DeclarationName::CXXConstructorName &&
491 Kind <= DeclarationName::CXXConversionFunctionName &&
492 "Kind must be a C++ special name kind");
Mike Stump11289f42009-09-09 15:08:12 +0000493 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor77324f32008-11-17 14:58:09 +0000494 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
495
496 DeclarationNameExtra::ExtraKind EKind;
497 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000498 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000499 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000500 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000501 break;
502 case DeclarationName::CXXDestructorName:
503 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000504 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000505 break;
506 case DeclarationName::CXXConversionFunctionName:
507 EKind = DeclarationNameExtra::CXXConversionFunction;
508 break;
509 default:
510 return DeclarationName();
511 }
512
513 // Unique selector, to guarantee there is one per name.
514 llvm::FoldingSetNodeID ID;
515 ID.AddInteger(EKind);
516 ID.AddPointer(Ty.getAsOpaquePtr());
517
Craig Topper36250ad2014-05-12 05:36:57 +0000518 void *InsertPos = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000519 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
520 return DeclarationName(Name);
521
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000522 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000523 SpecialName->ExtraKindOrNumArgs = EKind;
524 SpecialName->Type = Ty;
Craig Topper36250ad2014-05-12 05:36:57 +0000525 SpecialName->FETokenInfo = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000526
527 SpecialNames->InsertNode(SpecialName, InsertPos);
528 return DeclarationName(SpecialName);
529}
530
Mike Stump11289f42009-09-09 15:08:12 +0000531DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000532DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
533 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
534}
535
Alexis Hunt3d221f22009-11-29 07:34:05 +0000536DeclarationName
537DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000538 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
539 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
540 (CXXLiteralOperatorNames);
541
542 llvm::FoldingSetNodeID ID;
543 ID.AddPointer(II);
544
Craig Topper36250ad2014-05-12 05:36:57 +0000545 void *InsertPos = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000546 if (CXXLiteralOperatorIdName *Name =
547 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
548 return DeclarationName (Name);
549
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000550 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000551 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
552 LiteralName->ID = II;
Craig Topper36250ad2014-05-12 05:36:57 +0000553 LiteralName->FETokenInfo = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000554
555 LiteralNames->InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000556 return DeclarationName(LiteralName);
557}
558
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000559DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
560 switch (Name.getNameKind()) {
561 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000562 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000563 break;
564 case DeclarationName::CXXConstructorName:
565 case DeclarationName::CXXDestructorName:
566 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000567 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000568 break;
569 case DeclarationName::CXXOperatorName:
570 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
571 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
572 break;
573 case DeclarationName::CXXLiteralOperatorName:
574 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
575 break;
576 case DeclarationName::ObjCZeroArgSelector:
577 case DeclarationName::ObjCOneArgSelector:
578 case DeclarationName::ObjCMultiArgSelector:
579 // FIXME: ?
580 break;
581 case DeclarationName::CXXUsingDirective:
582 break;
583 }
584}
585
Douglas Gregora6e053e2010-12-15 01:34:56 +0000586bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
587 switch (Name.getNameKind()) {
588 case DeclarationName::Identifier:
589 case DeclarationName::ObjCZeroArgSelector:
590 case DeclarationName::ObjCOneArgSelector:
591 case DeclarationName::ObjCMultiArgSelector:
592 case DeclarationName::CXXOperatorName:
593 case DeclarationName::CXXLiteralOperatorName:
594 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000595 case DeclarationName::CXXDeductionGuideName:
Douglas Gregora6e053e2010-12-15 01:34:56 +0000596 return false;
597
598 case DeclarationName::CXXConstructorName:
599 case DeclarationName::CXXDestructorName:
600 case DeclarationName::CXXConversionFunctionName:
601 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
602 return TInfo->getType()->containsUnexpandedParameterPack();
603
604 return Name.getCXXNameType()->containsUnexpandedParameterPack();
605 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000606 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000607}
608
Douglas Gregor678d76c2011-07-01 01:22:09 +0000609bool DeclarationNameInfo::isInstantiationDependent() const {
610 switch (Name.getNameKind()) {
611 case DeclarationName::Identifier:
612 case DeclarationName::ObjCZeroArgSelector:
613 case DeclarationName::ObjCOneArgSelector:
614 case DeclarationName::ObjCMultiArgSelector:
615 case DeclarationName::CXXOperatorName:
616 case DeclarationName::CXXLiteralOperatorName:
617 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000618 case DeclarationName::CXXDeductionGuideName:
Douglas Gregor678d76c2011-07-01 01:22:09 +0000619 return false;
620
621 case DeclarationName::CXXConstructorName:
622 case DeclarationName::CXXDestructorName:
623 case DeclarationName::CXXConversionFunctionName:
624 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
625 return TInfo->getType()->isInstantiationDependentType();
626
627 return Name.getCXXNameType()->isInstantiationDependentType();
628 }
629 llvm_unreachable("All name kinds handled.");
630}
631
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000632std::string DeclarationNameInfo::getAsString() const {
633 std::string Result;
634 llvm::raw_string_ostream OS(Result);
635 printName(OS);
636 return OS.str();
637}
638
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000639void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000640 switch (Name.getNameKind()) {
641 case DeclarationName::Identifier:
642 case DeclarationName::ObjCZeroArgSelector:
643 case DeclarationName::ObjCOneArgSelector:
644 case DeclarationName::ObjCMultiArgSelector:
645 case DeclarationName::CXXOperatorName:
646 case DeclarationName::CXXLiteralOperatorName:
647 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000648 case DeclarationName::CXXDeductionGuideName:
David Blaikied4da8722013-05-14 21:04:00 +0000649 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000650 return;
651
652 case DeclarationName::CXXConstructorName:
653 case DeclarationName::CXXDestructorName:
654 case DeclarationName::CXXConversionFunctionName:
655 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
656 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
657 OS << '~';
658 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
659 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000660 LangOptions LO;
661 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000662 LO.Bool = true;
Alex Lorenza981c7d2017-04-11 16:46:03 +0000663 PrintingPolicy PP(LO);
664 PP.SuppressScope = true;
665 OS << TInfo->getType().getAsString(PP);
David Blaikied4da8722013-05-14 21:04:00 +0000666 } else
667 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000668 return;
669 }
David Blaikie83d382b2011-09-23 05:06:16 +0000670 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000671}
672
673SourceLocation DeclarationNameInfo::getEndLoc() const {
674 switch (Name.getNameKind()) {
675 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000676 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000677 return NameLoc;
678
679 case DeclarationName::CXXOperatorName: {
680 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
681 return SourceLocation::getFromRawEncoding(raw);
682 }
683
684 case DeclarationName::CXXLiteralOperatorName: {
685 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
686 return SourceLocation::getFromRawEncoding(raw);
687 }
688
689 case DeclarationName::CXXConstructorName:
690 case DeclarationName::CXXDestructorName:
691 case DeclarationName::CXXConversionFunctionName:
692 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
693 return TInfo->getTypeLoc().getEndLoc();
694 else
695 return NameLoc;
696
697 // DNInfo work in progress: FIXME.
698 case DeclarationName::ObjCZeroArgSelector:
699 case DeclarationName::ObjCOneArgSelector:
700 case DeclarationName::ObjCMultiArgSelector:
701 case DeclarationName::CXXUsingDirective:
702 return NameLoc;
703 }
David Blaikie83d382b2011-09-23 05:06:16 +0000704 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000705}