blob: f2c152f918ebf6f70a669b7602bed2cbd09d197a [file] [log] [blame]
Eugene Zelenko21fadad2017-11-21 23:26:08 +00001//===- DeclarationName.cpp - Declaration names implementation -------------===//
Douglas Gregor77324f32008-11-17 14:58:09 +00002//
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//===----------------------------------------------------------------------===//
Eugene Zelenko21fadad2017-11-21 23:26:08 +000014
Mehdi Amini9670f842016-07-18 19:02:11 +000015#include "clang/AST/DeclarationName.h"
Ted Kremenek6aead3a2010-05-10 20:40:08 +000016#include "clang/AST/ASTContext.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000017#include "clang/AST/Decl.h"
18#include "clang/AST/DeclBase.h"
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +000019#include "clang/AST/DeclCXX.h"
Richard Smith35845152017-02-07 01:37:30 +000020#include "clang/AST/DeclTemplate.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000021#include "clang/AST/PrettyPrinter.h"
Douglas Gregor92751d42008-11-17 22:58:34 +000022#include "clang/AST/Type.h"
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000023#include "clang/AST/TypeLoc.h"
Douglas Gregorb082bab2009-11-04 22:24:30 +000024#include "clang/AST/TypeOrdering.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000025#include "clang/Basic/IdentifierTable.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000026#include "clang/Basic/LLVM.h"
27#include "clang/Basic/LangOptions.h"
28#include "clang/Basic/OperatorKinds.h"
29#include "clang/Basic/SourceLocation.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000030#include "llvm/ADT/FoldingSet.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000031#include "llvm/Support/Casting.h"
32#include "llvm/Support/Compiler.h"
Chandler Carruth2b59fbe2010-12-15 07:29:18 +000033#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer95c7c422010-04-17 09:56:45 +000034#include "llvm/Support/raw_ostream.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000035#include <algorithm>
36#include <cassert>
37#include <cstdint>
38#include <string>
39
Douglas Gregor77324f32008-11-17 14:58:09 +000040using namespace clang;
41
John McCallef3057c2010-02-13 01:04:05 +000042static int compareInt(unsigned A, unsigned B) {
43 return (A < B ? -1 : (A > B ? 1 : 0));
44}
45
46int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregorb082bab2009-11-04 22:24:30 +000047 if (LHS.getNameKind() != RHS.getNameKind())
John McCallef3057c2010-02-13 01:04:05 +000048 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Fangrui Song6907ce22018-07-30 19:24:48 +000049
Douglas Gregorb082bab2009-11-04 22:24:30 +000050 switch (LHS.getNameKind()) {
John McCallef3057c2010-02-13 01:04:05 +000051 case DeclarationName::Identifier: {
Bruno Ricci366ba732018-09-21 12:53:22 +000052 IdentifierInfo *LII = LHS.castAsIdentifierInfo();
53 IdentifierInfo *RII = RHS.castAsIdentifierInfo();
54 if (!LII)
55 return RII ? -1 : 0;
56 if (!RII)
57 return 1;
Fangrui Song6907ce22018-07-30 19:24:48 +000058
John McCallef3057c2010-02-13 01:04:05 +000059 return LII->getName().compare(RII->getName());
60 }
Douglas Gregor77324f32008-11-17 14:58:09 +000061
Douglas Gregorb082bab2009-11-04 22:24:30 +000062 case DeclarationName::ObjCZeroArgSelector:
63 case DeclarationName::ObjCOneArgSelector:
64 case DeclarationName::ObjCMultiArgSelector: {
65 Selector LHSSelector = LHS.getObjCSelector();
66 Selector RHSSelector = RHS.getObjCSelector();
Manman Renb6665732016-11-17 18:41:18 +000067 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
68 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
69 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
70 return LHSSelector.getAsIdentifierInfo()->getName().compare(
Bruno Ricci366ba732018-09-21 12:53:22 +000071 RHSSelector.getAsIdentifierInfo()->getName());
Manman Renb6665732016-11-17 18:41:18 +000072 }
John McCallef3057c2010-02-13 01:04:05 +000073 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
74 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +000075 switch (LHSSelector.getNameForSlot(I).compare(
Bruno Ricci366ba732018-09-21 12:53:22 +000076 RHSSelector.getNameForSlot(I))) {
77 case -1:
78 return -1;
79 case 1:
80 return 1;
81 default:
82 break;
Douglas Gregorb082bab2009-11-04 22:24:30 +000083 }
84 }
John McCallef3057c2010-02-13 01:04:05 +000085
86 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +000087 }
Fangrui Song6907ce22018-07-30 19:24:48 +000088
Douglas Gregorb082bab2009-11-04 22:24:30 +000089 case DeclarationName::CXXConstructorName:
90 case DeclarationName::CXXDestructorName:
91 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +000092 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
93 return -1;
94 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
95 return 1;
96 return 0;
Richard Smith35845152017-02-07 01:37:30 +000097
98 case DeclarationName::CXXDeductionGuideName:
99 // We never want to compare deduction guide names for templates from
100 // different scopes, so just compare the template-name.
101 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
102 RHS.getCXXDeductionGuideTemplate()->getDeclName());
103
Douglas Gregorb082bab2009-11-04 22:24:30 +0000104 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000105 return compareInt(LHS.getCXXOverloadedOperator(),
106 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000107
108 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000109 return LHS.getCXXLiteralIdentifier()->getName().compare(
Bruno Ricci366ba732018-09-21 12:53:22 +0000110 RHS.getCXXLiteralIdentifier()->getName());
Fangrui Song6907ce22018-07-30 19:24:48 +0000111
Douglas Gregorb082bab2009-11-04 22:24:30 +0000112 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000113 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000114 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000115
116 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000117}
118
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000119static void printCXXConstructorDestructorName(QualType ClassType,
120 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000121 PrintingPolicy Policy) {
122 // We know we're printing C++ here. Ensure we print types properly.
123 Policy.adjustForCPlusPlus();
124
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000125 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
126 OS << *ClassRec->getDecl();
127 return;
128 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000129 if (Policy.SuppressTemplateArgsInCXXConstructors) {
130 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
131 OS << *InjTy->getDecl();
132 return;
133 }
134 }
Richard Smith301bc212016-05-19 01:39:10 +0000135 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000136}
137
138void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
Bruno Ricci366ba732018-09-21 12:53:22 +0000139 switch (getNameKind()) {
David Blaikied4da8722013-05-14 21:04:00 +0000140 case DeclarationName::Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000141 if (const IdentifierInfo *II = getAsIdentifierInfo())
David Blaikied4da8722013-05-14 21:04:00 +0000142 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000143 return;
David Blaikied4da8722013-05-14 21:04:00 +0000144
145 case DeclarationName::ObjCZeroArgSelector:
146 case DeclarationName::ObjCOneArgSelector:
147 case DeclarationName::ObjCMultiArgSelector:
Bruno Ricci366ba732018-09-21 12:53:22 +0000148 getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000149 return;
David Blaikied4da8722013-05-14 21:04:00 +0000150
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000151 case DeclarationName::CXXConstructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000152 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000153
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000154 case DeclarationName::CXXDestructorName:
David Blaikied4da8722013-05-14 21:04:00 +0000155 OS << '~';
Bruno Ricci366ba732018-09-21 12:53:22 +0000156 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000157
Richard Smith35845152017-02-07 01:37:30 +0000158 case DeclarationName::CXXDeductionGuideName:
Richard Smithf283fdc2017-02-08 00:35:25 +0000159 OS << "<deduction guide for ";
160 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
161 OS << '>';
162 return;
Richard Smith35845152017-02-07 01:37:30 +0000163
David Blaikied4da8722013-05-14 21:04:00 +0000164 case DeclarationName::CXXOperatorName: {
Bruno Ricci366ba732018-09-21 12:53:22 +0000165 static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
166 nullptr,
167#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
168 Spelling,
David Blaikied4da8722013-05-14 21:04:00 +0000169#include "clang/Basic/OperatorKinds.def"
170 };
Bruno Ricci366ba732018-09-21 12:53:22 +0000171 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
David Blaikied4da8722013-05-14 21:04:00 +0000172 assert(OpName && "not an overloaded operator");
173
174 OS << "operator";
175 if (OpName[0] >= 'a' && OpName[0] <= 'z')
176 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000177 OS << OpName;
178 return;
David Blaikied4da8722013-05-14 21:04:00 +0000179 }
180
181 case DeclarationName::CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000182 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000183 return;
David Blaikied4da8722013-05-14 21:04:00 +0000184
185 case DeclarationName::CXXConversionFunctionName: {
186 OS << "operator ";
Bruno Ricci366ba732018-09-21 12:53:22 +0000187 QualType Type = getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000188 if (const RecordType *Rec = Type->getAs<RecordType>()) {
189 OS << *Rec->getDecl();
190 return;
191 }
Richard Smith301bc212016-05-19 01:39:10 +0000192 // We know we're printing C++ here, ensure we print 'bool' properly.
193 PrintingPolicy CXXPolicy = Policy;
194 CXXPolicy.adjustForCPlusPlus();
195 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000196 return;
David Blaikied4da8722013-05-14 21:04:00 +0000197 }
198 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000199 OS << "<using-directive>";
200 return;
David Blaikied4da8722013-05-14 21:04:00 +0000201 }
202
203 llvm_unreachable("Unexpected declaration name kind");
204}
205
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000206namespace clang {
207
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000208raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
209 LangOptions LO;
210 N.print(OS, PrintingPolicy(LO));
211 return OS;
212}
213
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000214} // namespace clang
Douglas Gregor77324f32008-11-17 14:58:09 +0000215
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000216bool DeclarationName::isDependentName() const {
217 QualType T = getCXXNameType();
Richard Smith35845152017-02-07 01:37:30 +0000218 if (!T.isNull() && T->isDependentType())
219 return true;
220
221 // A class-scope deduction guide in a dependent context has a dependent name.
222 auto *TD = getCXXDeductionGuideTemplate();
223 if (TD && TD->getDeclContext()->isDependentContext())
224 return true;
225
226 return false;
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000227}
228
Douglas Gregor92751d42008-11-17 22:58:34 +0000229std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000230 std::string Result;
231 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000232 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000233 return OS.str();
234}
235
Bruno Ricci366ba732018-09-21 12:53:22 +0000236void *DeclarationName::getFETokenInfoSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000237 switch (getNameKind()) {
238 case Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000239 llvm_unreachable("case Identifier already handled by getFETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000240 case CXXConstructorName:
241 case CXXDestructorName:
242 case CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000243 return castAsCXXSpecialNameExtra()->FETokenInfo;
Douglas Gregor163c5852008-11-18 14:39:36 +0000244 case CXXOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000245 return castAsCXXOperatorIdName()->FETokenInfo;
246 case CXXDeductionGuideName:
247 return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000248 case CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000249 return castAsCXXLiteralOperatorIdName()->FETokenInfo;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000250 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000251 llvm_unreachable("DeclarationName has no FETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000252 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000253}
254
Bruno Ricci366ba732018-09-21 12:53:22 +0000255void DeclarationName::setFETokenInfoSlow(void *T) {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000256 switch (getNameKind()) {
257 case Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000258 llvm_unreachable("case Identifier already handled by setFETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000259 case CXXConstructorName:
260 case CXXDestructorName:
261 case CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000262 castAsCXXSpecialNameExtra()->FETokenInfo = T;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000263 break;
Douglas Gregor163c5852008-11-18 14:39:36 +0000264 case CXXOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000265 castAsCXXOperatorIdName()->FETokenInfo = T;
Douglas Gregor163c5852008-11-18 14:39:36 +0000266 break;
Bruno Ricci366ba732018-09-21 12:53:22 +0000267 case CXXDeductionGuideName:
268 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
269 break;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000270 case CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000271 castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000272 break;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000273 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000274 llvm_unreachable("DeclarationName has no FETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000275 }
276}
277
Yaron Kerencdae9412016-01-29 19:38:18 +0000278LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000279 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000280}
281
Jay Foad39c79802011-01-12 09:06:06 +0000282DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor163c5852008-11-18 14:39:36 +0000283 // Initialize the overloaded operator names.
Bruno Ricci366ba732018-09-21 12:53:22 +0000284 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
285 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000286}
287
288DeclarationName
Richard Smith35845152017-02-07 01:37:30 +0000289DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
290 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
291
Richard Smith35845152017-02-07 01:37:30 +0000292 llvm::FoldingSetNodeID ID;
293 ID.AddPointer(Template);
294
295 void *InsertPos = nullptr;
Bruno Riccib6198832018-08-06 16:47:31 +0000296 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
Richard Smith35845152017-02-07 01:37:30 +0000297 return DeclarationName(Name);
298
Bruno Ricci366ba732018-09-21 12:53:22 +0000299 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
Bruno Riccib6198832018-08-06 16:47:31 +0000300 CXXDeductionGuideNames.InsertNode(Name, InsertPos);
Richard Smith35845152017-02-07 01:37:30 +0000301 return DeclarationName(Name);
302}
303
Bruno Ricci366ba732018-09-21 12:53:22 +0000304DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
305 // The type of constructors is unqualified.
306 Ty = Ty.getUnqualifiedType();
307 // Do we already have this C++ constructor name ?
308 llvm::FoldingSetNodeID ID;
309 ID.AddPointer(Ty.getAsOpaquePtr());
310 void *InsertPos = nullptr;
311 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
312 return {Name, DeclarationName::StoredCXXConstructorName};
313
314 // We have to create it.
315 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
316 CXXConstructorNames.InsertNode(SpecialName, InsertPos);
317 return {SpecialName, DeclarationName::StoredCXXConstructorName};
318}
319
320DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
321 // The type of destructors is unqualified.
322 Ty = Ty.getUnqualifiedType();
323 // Do we already have this C++ destructor name ?
324 llvm::FoldingSetNodeID ID;
325 ID.AddPointer(Ty.getAsOpaquePtr());
326 void *InsertPos = nullptr;
327 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
328 return {Name, DeclarationName::StoredCXXDestructorName};
329
330 // We have to create it.
331 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
332 CXXDestructorNames.InsertNode(SpecialName, InsertPos);
333 return {SpecialName, DeclarationName::StoredCXXDestructorName};
334}
335
Richard Smith35845152017-02-07 01:37:30 +0000336DeclarationName
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000337DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
Bruno Ricci366ba732018-09-21 12:53:22 +0000338 // Do we already have this C++ conversion function name ?
339 llvm::FoldingSetNodeID ID;
340 ID.AddPointer(Ty.getAsOpaquePtr());
341 void *InsertPos = nullptr;
342 if (auto *Name =
343 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
344 return {Name, DeclarationName::StoredCXXConversionFunctionName};
345
346 // We have to create it.
347 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
348 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
349 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000350}
351
Mike Stump11289f42009-09-09 15:08:12 +0000352DeclarationName
353DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000354 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000355 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000356 case DeclarationName::CXXConstructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000357 return getCXXConstructorName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000358 case DeclarationName::CXXDestructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000359 return getCXXDestructorName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000360 case DeclarationName::CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000361 return getCXXConversionFunctionName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000362 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000363 llvm_unreachable("Invalid kind in getCXXSpecialName!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000364 }
Douglas Gregor163c5852008-11-18 14:39:36 +0000365}
366
Alexis Hunt3d221f22009-11-29 07:34:05 +0000367DeclarationName
368DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000369 llvm::FoldingSetNodeID ID;
370 ID.AddPointer(II);
371
Craig Topper36250ad2014-05-12 05:36:57 +0000372 void *InsertPos = nullptr;
Bruno Ricci366ba732018-09-21 12:53:22 +0000373 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
374 return DeclarationName(Name);
Fangrui Song6907ce22018-07-30 19:24:48 +0000375
Bruno Ricci366ba732018-09-21 12:53:22 +0000376 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
Bruno Riccib6198832018-08-06 16:47:31 +0000377 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000378 return DeclarationName(LiteralName);
379}
380
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000381DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
382 switch (Name.getNameKind()) {
383 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000384 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000385 break;
386 case DeclarationName::CXXConstructorName:
387 case DeclarationName::CXXDestructorName:
388 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000389 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000390 break;
391 case DeclarationName::CXXOperatorName:
392 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
393 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
394 break;
395 case DeclarationName::CXXLiteralOperatorName:
396 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
397 break;
398 case DeclarationName::ObjCZeroArgSelector:
399 case DeclarationName::ObjCOneArgSelector:
400 case DeclarationName::ObjCMultiArgSelector:
401 // FIXME: ?
402 break;
403 case DeclarationName::CXXUsingDirective:
404 break;
405 }
406}
407
Douglas Gregora6e053e2010-12-15 01:34:56 +0000408bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
409 switch (Name.getNameKind()) {
410 case DeclarationName::Identifier:
411 case DeclarationName::ObjCZeroArgSelector:
412 case DeclarationName::ObjCOneArgSelector:
413 case DeclarationName::ObjCMultiArgSelector:
414 case DeclarationName::CXXOperatorName:
415 case DeclarationName::CXXLiteralOperatorName:
416 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000417 case DeclarationName::CXXDeductionGuideName:
Douglas Gregora6e053e2010-12-15 01:34:56 +0000418 return false;
419
420 case DeclarationName::CXXConstructorName:
421 case DeclarationName::CXXDestructorName:
422 case DeclarationName::CXXConversionFunctionName:
423 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
424 return TInfo->getType()->containsUnexpandedParameterPack();
425
426 return Name.getCXXNameType()->containsUnexpandedParameterPack();
427 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000428 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000429}
430
Douglas Gregor678d76c2011-07-01 01:22:09 +0000431bool DeclarationNameInfo::isInstantiationDependent() const {
432 switch (Name.getNameKind()) {
433 case DeclarationName::Identifier:
434 case DeclarationName::ObjCZeroArgSelector:
435 case DeclarationName::ObjCOneArgSelector:
436 case DeclarationName::ObjCMultiArgSelector:
437 case DeclarationName::CXXOperatorName:
438 case DeclarationName::CXXLiteralOperatorName:
439 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000440 case DeclarationName::CXXDeductionGuideName:
Douglas Gregor678d76c2011-07-01 01:22:09 +0000441 return false;
Fangrui Song6907ce22018-07-30 19:24:48 +0000442
Douglas Gregor678d76c2011-07-01 01:22:09 +0000443 case DeclarationName::CXXConstructorName:
444 case DeclarationName::CXXDestructorName:
445 case DeclarationName::CXXConversionFunctionName:
446 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
447 return TInfo->getType()->isInstantiationDependentType();
Fangrui Song6907ce22018-07-30 19:24:48 +0000448
Douglas Gregor678d76c2011-07-01 01:22:09 +0000449 return Name.getCXXNameType()->isInstantiationDependentType();
450 }
451 llvm_unreachable("All name kinds handled.");
452}
453
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000454std::string DeclarationNameInfo::getAsString() const {
455 std::string Result;
456 llvm::raw_string_ostream OS(Result);
457 printName(OS);
458 return OS.str();
459}
460
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000461void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000462 switch (Name.getNameKind()) {
463 case DeclarationName::Identifier:
464 case DeclarationName::ObjCZeroArgSelector:
465 case DeclarationName::ObjCOneArgSelector:
466 case DeclarationName::ObjCMultiArgSelector:
467 case DeclarationName::CXXOperatorName:
468 case DeclarationName::CXXLiteralOperatorName:
469 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000470 case DeclarationName::CXXDeductionGuideName:
David Blaikied4da8722013-05-14 21:04:00 +0000471 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000472 return;
473
474 case DeclarationName::CXXConstructorName:
475 case DeclarationName::CXXDestructorName:
476 case DeclarationName::CXXConversionFunctionName:
477 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
478 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
479 OS << '~';
480 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
481 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000482 LangOptions LO;
483 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000484 LO.Bool = true;
Alex Lorenza981c7d2017-04-11 16:46:03 +0000485 PrintingPolicy PP(LO);
486 PP.SuppressScope = true;
487 OS << TInfo->getType().getAsString(PP);
David Blaikied4da8722013-05-14 21:04:00 +0000488 } else
489 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000490 return;
491 }
David Blaikie83d382b2011-09-23 05:06:16 +0000492 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000493}
494
Stephen Kellyf50288c2018-07-30 20:39:14 +0000495SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000496 switch (Name.getNameKind()) {
497 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000498 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000499 return NameLoc;
500
501 case DeclarationName::CXXOperatorName: {
502 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
503 return SourceLocation::getFromRawEncoding(raw);
504 }
505
506 case DeclarationName::CXXLiteralOperatorName: {
507 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
508 return SourceLocation::getFromRawEncoding(raw);
509 }
510
511 case DeclarationName::CXXConstructorName:
512 case DeclarationName::CXXDestructorName:
513 case DeclarationName::CXXConversionFunctionName:
514 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
515 return TInfo->getTypeLoc().getEndLoc();
516 else
517 return NameLoc;
518
519 // DNInfo work in progress: FIXME.
520 case DeclarationName::ObjCZeroArgSelector:
521 case DeclarationName::ObjCOneArgSelector:
522 case DeclarationName::ObjCMultiArgSelector:
523 case DeclarationName::CXXUsingDirective:
524 return NameLoc;
525 }
David Blaikie83d382b2011-09-23 05:06:16 +0000526 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000527}