blob: 273a1fec0947c32a70d96f474a542e695fdbfa8d [file] [log] [blame]
Eugene Zelenko21fadad2017-11-21 23:26:08 +00001//===- DeclarationName.cpp - Declaration names implementation -------------===//
Douglas Gregor77324f32008-11-17 14:58:09 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Douglas Gregor77324f32008-11-17 14:58:09 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the DeclarationName and DeclarationNameTable
10// classes.
11//
12//===----------------------------------------------------------------------===//
Eugene Zelenko21fadad2017-11-21 23:26:08 +000013
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"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000016#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +000018#include "clang/AST/DeclCXX.h"
Richard Smith35845152017-02-07 01:37:30 +000019#include "clang/AST/DeclTemplate.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000020#include "clang/AST/PrettyPrinter.h"
Douglas Gregor92751d42008-11-17 22:58:34 +000021#include "clang/AST/Type.h"
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregorb082bab2009-11-04 22:24:30 +000023#include "clang/AST/TypeOrdering.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000024#include "clang/Basic/IdentifierTable.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000025#include "clang/Basic/LLVM.h"
26#include "clang/Basic/LangOptions.h"
27#include "clang/Basic/OperatorKinds.h"
28#include "clang/Basic/SourceLocation.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000029#include "llvm/ADT/FoldingSet.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000030#include "llvm/Support/Casting.h"
31#include "llvm/Support/Compiler.h"
Chandler Carruth2b59fbe2010-12-15 07:29:18 +000032#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer95c7c422010-04-17 09:56:45 +000033#include "llvm/Support/raw_ostream.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000034#include <algorithm>
35#include <cassert>
36#include <cstdint>
37#include <string>
38
Douglas Gregor77324f32008-11-17 14:58:09 +000039using namespace clang;
40
John McCallef3057c2010-02-13 01:04:05 +000041static int compareInt(unsigned A, unsigned B) {
42 return (A < B ? -1 : (A > B ? 1 : 0));
43}
44
45int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregorb082bab2009-11-04 22:24:30 +000046 if (LHS.getNameKind() != RHS.getNameKind())
John McCallef3057c2010-02-13 01:04:05 +000047 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Fangrui Song6907ce22018-07-30 19:24:48 +000048
Douglas Gregorb082bab2009-11-04 22:24:30 +000049 switch (LHS.getNameKind()) {
John McCallef3057c2010-02-13 01:04:05 +000050 case DeclarationName::Identifier: {
Bruno Ricci366ba732018-09-21 12:53:22 +000051 IdentifierInfo *LII = LHS.castAsIdentifierInfo();
52 IdentifierInfo *RII = RHS.castAsIdentifierInfo();
53 if (!LII)
54 return RII ? -1 : 0;
55 if (!RII)
56 return 1;
Fangrui Song6907ce22018-07-30 19:24:48 +000057
John McCallef3057c2010-02-13 01:04:05 +000058 return LII->getName().compare(RII->getName());
59 }
Douglas Gregor77324f32008-11-17 14:58:09 +000060
Douglas Gregorb082bab2009-11-04 22:24:30 +000061 case DeclarationName::ObjCZeroArgSelector:
62 case DeclarationName::ObjCOneArgSelector:
63 case DeclarationName::ObjCMultiArgSelector: {
64 Selector LHSSelector = LHS.getObjCSelector();
65 Selector RHSSelector = RHS.getObjCSelector();
Manman Renb6665732016-11-17 18:41:18 +000066 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
67 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
68 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
69 return LHSSelector.getAsIdentifierInfo()->getName().compare(
Bruno Ricci366ba732018-09-21 12:53:22 +000070 RHSSelector.getAsIdentifierInfo()->getName());
Manman Renb6665732016-11-17 18:41:18 +000071 }
John McCallef3057c2010-02-13 01:04:05 +000072 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
73 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +000074 switch (LHSSelector.getNameForSlot(I).compare(
Bruno Ricci366ba732018-09-21 12:53:22 +000075 RHSSelector.getNameForSlot(I))) {
76 case -1:
77 return -1;
78 case 1:
79 return 1;
80 default:
81 break;
Douglas Gregorb082bab2009-11-04 22:24:30 +000082 }
83 }
John McCallef3057c2010-02-13 01:04:05 +000084
85 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +000086 }
Fangrui Song6907ce22018-07-30 19:24:48 +000087
Douglas Gregorb082bab2009-11-04 22:24:30 +000088 case DeclarationName::CXXConstructorName:
89 case DeclarationName::CXXDestructorName:
90 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +000091 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
92 return -1;
93 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
94 return 1;
95 return 0;
Richard Smith35845152017-02-07 01:37:30 +000096
97 case DeclarationName::CXXDeductionGuideName:
98 // We never want to compare deduction guide names for templates from
99 // different scopes, so just compare the template-name.
100 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
101 RHS.getCXXDeductionGuideTemplate()->getDeclName());
102
Douglas Gregorb082bab2009-11-04 22:24:30 +0000103 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000104 return compareInt(LHS.getCXXOverloadedOperator(),
105 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000106
107 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000108 return LHS.getCXXLiteralIdentifier()->getName().compare(
Bruno Ricci366ba732018-09-21 12:53:22 +0000109 RHS.getCXXLiteralIdentifier()->getName());
Fangrui Song6907ce22018-07-30 19:24:48 +0000110
Douglas Gregorb082bab2009-11-04 22:24:30 +0000111 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000112 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000113 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000114
115 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000116}
117
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000118static void printCXXConstructorDestructorName(QualType ClassType,
119 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000120 PrintingPolicy Policy) {
121 // We know we're printing C++ here. Ensure we print types properly.
122 Policy.adjustForCPlusPlus();
123
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000124 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
125 OS << *ClassRec->getDecl();
126 return;
127 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000128 if (Policy.SuppressTemplateArgsInCXXConstructors) {
129 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
130 OS << *InjTy->getDecl();
131 return;
132 }
133 }
Richard Smith301bc212016-05-19 01:39:10 +0000134 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000135}
136
137void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
Bruno Ricci366ba732018-09-21 12:53:22 +0000138 switch (getNameKind()) {
David Blaikied4da8722013-05-14 21:04:00 +0000139 case DeclarationName::Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000140 if (const IdentifierInfo *II = getAsIdentifierInfo())
David Blaikied4da8722013-05-14 21:04:00 +0000141 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000142 return;
David Blaikied4da8722013-05-14 21:04:00 +0000143
144 case DeclarationName::ObjCZeroArgSelector:
145 case DeclarationName::ObjCOneArgSelector:
146 case DeclarationName::ObjCMultiArgSelector:
Bruno Ricci366ba732018-09-21 12:53:22 +0000147 getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000148 return;
David Blaikied4da8722013-05-14 21:04:00 +0000149
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000150 case DeclarationName::CXXConstructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000151 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000152
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000153 case DeclarationName::CXXDestructorName:
David Blaikied4da8722013-05-14 21:04:00 +0000154 OS << '~';
Bruno Ricci366ba732018-09-21 12:53:22 +0000155 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000156
Richard Smith35845152017-02-07 01:37:30 +0000157 case DeclarationName::CXXDeductionGuideName:
Richard Smithf283fdc2017-02-08 00:35:25 +0000158 OS << "<deduction guide for ";
159 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
160 OS << '>';
161 return;
Richard Smith35845152017-02-07 01:37:30 +0000162
David Blaikied4da8722013-05-14 21:04:00 +0000163 case DeclarationName::CXXOperatorName: {
Bruno Ricci366ba732018-09-21 12:53:22 +0000164 static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165 nullptr,
166#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
167 Spelling,
David Blaikied4da8722013-05-14 21:04:00 +0000168#include "clang/Basic/OperatorKinds.def"
169 };
Bruno Ricci366ba732018-09-21 12:53:22 +0000170 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
David Blaikied4da8722013-05-14 21:04:00 +0000171 assert(OpName && "not an overloaded operator");
172
173 OS << "operator";
174 if (OpName[0] >= 'a' && OpName[0] <= 'z')
175 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000176 OS << OpName;
177 return;
David Blaikied4da8722013-05-14 21:04:00 +0000178 }
179
180 case DeclarationName::CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000181 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000182 return;
David Blaikied4da8722013-05-14 21:04:00 +0000183
184 case DeclarationName::CXXConversionFunctionName: {
185 OS << "operator ";
Bruno Ricci366ba732018-09-21 12:53:22 +0000186 QualType Type = getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000187 if (const RecordType *Rec = Type->getAs<RecordType>()) {
188 OS << *Rec->getDecl();
189 return;
190 }
Richard Smith301bc212016-05-19 01:39:10 +0000191 // We know we're printing C++ here, ensure we print 'bool' properly.
192 PrintingPolicy CXXPolicy = Policy;
193 CXXPolicy.adjustForCPlusPlus();
194 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000195 return;
David Blaikied4da8722013-05-14 21:04:00 +0000196 }
197 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000198 OS << "<using-directive>";
199 return;
David Blaikied4da8722013-05-14 21:04:00 +0000200 }
201
202 llvm_unreachable("Unexpected declaration name kind");
203}
204
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000205namespace clang {
206
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000207raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
208 LangOptions LO;
209 N.print(OS, PrintingPolicy(LO));
210 return OS;
211}
212
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000213} // namespace clang
Douglas Gregor77324f32008-11-17 14:58:09 +0000214
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000215bool DeclarationName::isDependentName() const {
216 QualType T = getCXXNameType();
Richard Smith35845152017-02-07 01:37:30 +0000217 if (!T.isNull() && T->isDependentType())
218 return true;
219
220 // A class-scope deduction guide in a dependent context has a dependent name.
221 auto *TD = getCXXDeductionGuideTemplate();
222 if (TD && TD->getDeclContext()->isDependentContext())
223 return true;
224
225 return false;
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000226}
227
Douglas Gregor92751d42008-11-17 22:58:34 +0000228std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000229 std::string Result;
230 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000231 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000232 return OS.str();
233}
234
Bruno Ricci366ba732018-09-21 12:53:22 +0000235void *DeclarationName::getFETokenInfoSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000236 switch (getNameKind()) {
237 case Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000238 llvm_unreachable("case Identifier already handled by getFETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000239 case CXXConstructorName:
240 case CXXDestructorName:
241 case CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000242 return castAsCXXSpecialNameExtra()->FETokenInfo;
Douglas Gregor163c5852008-11-18 14:39:36 +0000243 case CXXOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000244 return castAsCXXOperatorIdName()->FETokenInfo;
245 case CXXDeductionGuideName:
246 return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000247 case CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000248 return castAsCXXLiteralOperatorIdName()->FETokenInfo;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000249 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000250 llvm_unreachable("DeclarationName has no FETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000251 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000252}
253
Bruno Ricci366ba732018-09-21 12:53:22 +0000254void DeclarationName::setFETokenInfoSlow(void *T) {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000255 switch (getNameKind()) {
256 case Identifier:
Bruno Ricci366ba732018-09-21 12:53:22 +0000257 llvm_unreachable("case Identifier already handled by setFETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000258 case CXXConstructorName:
259 case CXXDestructorName:
260 case CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000261 castAsCXXSpecialNameExtra()->FETokenInfo = T;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000262 break;
Douglas Gregor163c5852008-11-18 14:39:36 +0000263 case CXXOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000264 castAsCXXOperatorIdName()->FETokenInfo = T;
Douglas Gregor163c5852008-11-18 14:39:36 +0000265 break;
Bruno Ricci366ba732018-09-21 12:53:22 +0000266 case CXXDeductionGuideName:
267 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
268 break;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000269 case CXXLiteralOperatorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000270 castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000271 break;
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000272 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000273 llvm_unreachable("DeclarationName has no FETokenInfo!");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000274 }
275}
276
Yaron Kerencdae9412016-01-29 19:38:18 +0000277LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000278 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000279}
280
Jay Foad39c79802011-01-12 09:06:06 +0000281DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor163c5852008-11-18 14:39:36 +0000282 // Initialize the overloaded operator names.
Bruno Ricci366ba732018-09-21 12:53:22 +0000283 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
284 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000285}
286
287DeclarationName
Richard Smith35845152017-02-07 01:37:30 +0000288DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
289 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
290
Richard Smith35845152017-02-07 01:37:30 +0000291 llvm::FoldingSetNodeID ID;
292 ID.AddPointer(Template);
293
294 void *InsertPos = nullptr;
Bruno Riccib6198832018-08-06 16:47:31 +0000295 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
Richard Smith35845152017-02-07 01:37:30 +0000296 return DeclarationName(Name);
297
Bruno Ricci366ba732018-09-21 12:53:22 +0000298 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
Bruno Riccib6198832018-08-06 16:47:31 +0000299 CXXDeductionGuideNames.InsertNode(Name, InsertPos);
Richard Smith35845152017-02-07 01:37:30 +0000300 return DeclarationName(Name);
301}
302
Bruno Ricci366ba732018-09-21 12:53:22 +0000303DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
304 // The type of constructors is unqualified.
305 Ty = Ty.getUnqualifiedType();
306 // Do we already have this C++ constructor name ?
307 llvm::FoldingSetNodeID ID;
308 ID.AddPointer(Ty.getAsOpaquePtr());
309 void *InsertPos = nullptr;
310 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
311 return {Name, DeclarationName::StoredCXXConstructorName};
312
313 // We have to create it.
314 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
315 CXXConstructorNames.InsertNode(SpecialName, InsertPos);
316 return {SpecialName, DeclarationName::StoredCXXConstructorName};
317}
318
319DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
320 // The type of destructors is unqualified.
321 Ty = Ty.getUnqualifiedType();
322 // Do we already have this C++ destructor name ?
323 llvm::FoldingSetNodeID ID;
324 ID.AddPointer(Ty.getAsOpaquePtr());
325 void *InsertPos = nullptr;
326 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
327 return {Name, DeclarationName::StoredCXXDestructorName};
328
329 // We have to create it.
330 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
331 CXXDestructorNames.InsertNode(SpecialName, InsertPos);
332 return {SpecialName, DeclarationName::StoredCXXDestructorName};
333}
334
Richard Smith35845152017-02-07 01:37:30 +0000335DeclarationName
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000336DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
Bruno Ricci366ba732018-09-21 12:53:22 +0000337 // Do we already have this C++ conversion function name ?
338 llvm::FoldingSetNodeID ID;
339 ID.AddPointer(Ty.getAsOpaquePtr());
340 void *InsertPos = nullptr;
341 if (auto *Name =
342 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
343 return {Name, DeclarationName::StoredCXXConversionFunctionName};
344
345 // We have to create it.
346 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
347 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
348 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000349}
350
Mike Stump11289f42009-09-09 15:08:12 +0000351DeclarationName
352DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000353 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000354 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000355 case DeclarationName::CXXConstructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000356 return getCXXConstructorName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000357 case DeclarationName::CXXDestructorName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000358 return getCXXDestructorName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000359 case DeclarationName::CXXConversionFunctionName:
Bruno Ricci366ba732018-09-21 12:53:22 +0000360 return getCXXConversionFunctionName(Ty);
Douglas Gregor77324f32008-11-17 14:58:09 +0000361 default:
Bruno Ricci366ba732018-09-21 12:53:22 +0000362 llvm_unreachable("Invalid kind in getCXXSpecialName!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000363 }
Douglas Gregor163c5852008-11-18 14:39:36 +0000364}
365
Alexis Hunt3d221f22009-11-29 07:34:05 +0000366DeclarationName
367DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000368 llvm::FoldingSetNodeID ID;
369 ID.AddPointer(II);
370
Craig Topper36250ad2014-05-12 05:36:57 +0000371 void *InsertPos = nullptr;
Bruno Ricci366ba732018-09-21 12:53:22 +0000372 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
373 return DeclarationName(Name);
Fangrui Song6907ce22018-07-30 19:24:48 +0000374
Bruno Ricci366ba732018-09-21 12:53:22 +0000375 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
Bruno Riccib6198832018-08-06 16:47:31 +0000376 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000377 return DeclarationName(LiteralName);
378}
379
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000380DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
381 switch (Name.getNameKind()) {
382 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000383 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000384 break;
385 case DeclarationName::CXXConstructorName:
386 case DeclarationName::CXXDestructorName:
387 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000388 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000389 break;
390 case DeclarationName::CXXOperatorName:
391 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
392 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
393 break;
394 case DeclarationName::CXXLiteralOperatorName:
395 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
396 break;
397 case DeclarationName::ObjCZeroArgSelector:
398 case DeclarationName::ObjCOneArgSelector:
399 case DeclarationName::ObjCMultiArgSelector:
400 // FIXME: ?
401 break;
402 case DeclarationName::CXXUsingDirective:
403 break;
404 }
405}
406
Douglas Gregora6e053e2010-12-15 01:34:56 +0000407bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
408 switch (Name.getNameKind()) {
409 case DeclarationName::Identifier:
410 case DeclarationName::ObjCZeroArgSelector:
411 case DeclarationName::ObjCOneArgSelector:
412 case DeclarationName::ObjCMultiArgSelector:
413 case DeclarationName::CXXOperatorName:
414 case DeclarationName::CXXLiteralOperatorName:
415 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000416 case DeclarationName::CXXDeductionGuideName:
Douglas Gregora6e053e2010-12-15 01:34:56 +0000417 return false;
418
419 case DeclarationName::CXXConstructorName:
420 case DeclarationName::CXXDestructorName:
421 case DeclarationName::CXXConversionFunctionName:
422 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
423 return TInfo->getType()->containsUnexpandedParameterPack();
424
425 return Name.getCXXNameType()->containsUnexpandedParameterPack();
426 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000427 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000428}
429
Douglas Gregor678d76c2011-07-01 01:22:09 +0000430bool DeclarationNameInfo::isInstantiationDependent() const {
431 switch (Name.getNameKind()) {
432 case DeclarationName::Identifier:
433 case DeclarationName::ObjCZeroArgSelector:
434 case DeclarationName::ObjCOneArgSelector:
435 case DeclarationName::ObjCMultiArgSelector:
436 case DeclarationName::CXXOperatorName:
437 case DeclarationName::CXXLiteralOperatorName:
438 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000439 case DeclarationName::CXXDeductionGuideName:
Douglas Gregor678d76c2011-07-01 01:22:09 +0000440 return false;
Fangrui Song6907ce22018-07-30 19:24:48 +0000441
Douglas Gregor678d76c2011-07-01 01:22:09 +0000442 case DeclarationName::CXXConstructorName:
443 case DeclarationName::CXXDestructorName:
444 case DeclarationName::CXXConversionFunctionName:
445 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
446 return TInfo->getType()->isInstantiationDependentType();
Fangrui Song6907ce22018-07-30 19:24:48 +0000447
Douglas Gregor678d76c2011-07-01 01:22:09 +0000448 return Name.getCXXNameType()->isInstantiationDependentType();
449 }
450 llvm_unreachable("All name kinds handled.");
451}
452
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000453std::string DeclarationNameInfo::getAsString() const {
454 std::string Result;
455 llvm::raw_string_ostream OS(Result);
456 printName(OS);
457 return OS.str();
458}
459
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000460void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000461 switch (Name.getNameKind()) {
462 case DeclarationName::Identifier:
463 case DeclarationName::ObjCZeroArgSelector:
464 case DeclarationName::ObjCOneArgSelector:
465 case DeclarationName::ObjCMultiArgSelector:
466 case DeclarationName::CXXOperatorName:
467 case DeclarationName::CXXLiteralOperatorName:
468 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000469 case DeclarationName::CXXDeductionGuideName:
David Blaikied4da8722013-05-14 21:04:00 +0000470 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000471 return;
472
473 case DeclarationName::CXXConstructorName:
474 case DeclarationName::CXXDestructorName:
475 case DeclarationName::CXXConversionFunctionName:
476 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
477 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
478 OS << '~';
479 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
480 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000481 LangOptions LO;
482 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000483 LO.Bool = true;
Alex Lorenza981c7d2017-04-11 16:46:03 +0000484 PrintingPolicy PP(LO);
485 PP.SuppressScope = true;
486 OS << TInfo->getType().getAsString(PP);
David Blaikied4da8722013-05-14 21:04:00 +0000487 } else
488 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000489 return;
490 }
David Blaikie83d382b2011-09-23 05:06:16 +0000491 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000492}
493
Stephen Kellyf50288c2018-07-30 20:39:14 +0000494SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000495 switch (Name.getNameKind()) {
496 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000497 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000498 return NameLoc;
499
500 case DeclarationName::CXXOperatorName: {
501 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
502 return SourceLocation::getFromRawEncoding(raw);
503 }
504
505 case DeclarationName::CXXLiteralOperatorName: {
506 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
507 return SourceLocation::getFromRawEncoding(raw);
508 }
509
510 case DeclarationName::CXXConstructorName:
511 case DeclarationName::CXXDestructorName:
512 case DeclarationName::CXXConversionFunctionName:
513 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514 return TInfo->getTypeLoc().getEndLoc();
515 else
516 return NameLoc;
517
518 // DNInfo work in progress: FIXME.
519 case DeclarationName::ObjCZeroArgSelector:
520 case DeclarationName::ObjCOneArgSelector:
521 case DeclarationName::ObjCMultiArgSelector:
522 case DeclarationName::CXXUsingDirective:
523 return NameLoc;
524 }
David Blaikie83d382b2011-09-23 05:06:16 +0000525 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000526}