blob: 843434107056980ff2f4fe06c6c8137f5354d98b [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: {
52 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
53 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
54 if (!LII) return RII ? -1 : 0;
55 if (!RII) return 1;
Fangrui Song6907ce22018-07-30 19:24:48 +000056
John McCallef3057c2010-02-13 01:04:05 +000057 return LII->getName().compare(RII->getName());
58 }
Douglas Gregor77324f32008-11-17 14:58:09 +000059
Douglas Gregorb082bab2009-11-04 22:24:30 +000060 case DeclarationName::ObjCZeroArgSelector:
61 case DeclarationName::ObjCOneArgSelector:
62 case DeclarationName::ObjCMultiArgSelector: {
63 Selector LHSSelector = LHS.getObjCSelector();
64 Selector RHSSelector = RHS.getObjCSelector();
Manman Renb6665732016-11-17 18:41:18 +000065 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
66 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
67 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
68 return LHSSelector.getAsIdentifierInfo()->getName().compare(
69 RHSSelector.getAsIdentifierInfo()->getName());
70 }
John McCallef3057c2010-02-13 01:04:05 +000071 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
72 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +000073 switch (LHSSelector.getNameForSlot(I).compare(
74 RHSSelector.getNameForSlot(I))) {
Manman Renb6665732016-11-17 18:41:18 +000075 case -1: return -1;
76 case 1: return 1;
Douglas Gregorb082bab2009-11-04 22:24:30 +000077 default: break;
78 }
79 }
John McCallef3057c2010-02-13 01:04:05 +000080
81 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +000082 }
Fangrui Song6907ce22018-07-30 19:24:48 +000083
Douglas Gregorb082bab2009-11-04 22:24:30 +000084 case DeclarationName::CXXConstructorName:
85 case DeclarationName::CXXDestructorName:
86 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +000087 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
88 return -1;
89 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
90 return 1;
91 return 0;
Richard Smith35845152017-02-07 01:37:30 +000092
93 case DeclarationName::CXXDeductionGuideName:
94 // We never want to compare deduction guide names for templates from
95 // different scopes, so just compare the template-name.
96 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
97 RHS.getCXXDeductionGuideTemplate()->getDeclName());
98
Douglas Gregorb082bab2009-11-04 22:24:30 +000099 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000100 return compareInt(LHS.getCXXOverloadedOperator(),
101 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000102
103 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000104 return LHS.getCXXLiteralIdentifier()->getName().compare(
105 RHS.getCXXLiteralIdentifier()->getName());
Fangrui Song6907ce22018-07-30 19:24:48 +0000106
Douglas Gregorb082bab2009-11-04 22:24:30 +0000107 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000108 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000109 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000110
111 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000112}
113
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000114static void printCXXConstructorDestructorName(QualType ClassType,
115 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000116 PrintingPolicy Policy) {
117 // We know we're printing C++ here. Ensure we print types properly.
118 Policy.adjustForCPlusPlus();
119
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000120 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
121 OS << *ClassRec->getDecl();
122 return;
123 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000124 if (Policy.SuppressTemplateArgsInCXXConstructors) {
125 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
126 OS << *InjTy->getDecl();
127 return;
128 }
129 }
Richard Smith301bc212016-05-19 01:39:10 +0000130 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000131}
132
133void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
134 DeclarationName &N = *this;
David Blaikied4da8722013-05-14 21:04:00 +0000135 switch (N.getNameKind()) {
136 case DeclarationName::Identifier:
137 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
138 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000139 return;
David Blaikied4da8722013-05-14 21:04:00 +0000140
141 case DeclarationName::ObjCZeroArgSelector:
142 case DeclarationName::ObjCOneArgSelector:
143 case DeclarationName::ObjCMultiArgSelector:
Aaron Ballmanb190f972014-01-03 17:59:55 +0000144 N.getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000145 return;
David Blaikied4da8722013-05-14 21:04:00 +0000146
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000147 case DeclarationName::CXXConstructorName:
148 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000149
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000150 case DeclarationName::CXXDestructorName:
David Blaikied4da8722013-05-14 21:04:00 +0000151 OS << '~';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000152 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000153
Richard Smith35845152017-02-07 01:37:30 +0000154 case DeclarationName::CXXDeductionGuideName:
Richard Smithf283fdc2017-02-08 00:35:25 +0000155 OS << "<deduction guide for ";
156 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
157 OS << '>';
158 return;
Richard Smith35845152017-02-07 01:37:30 +0000159
David Blaikied4da8722013-05-14 21:04:00 +0000160 case DeclarationName::CXXOperatorName: {
161 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Craig Topper36250ad2014-05-12 05:36:57 +0000162 nullptr,
David Blaikied4da8722013-05-14 21:04:00 +0000163#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
164 Spelling,
165#include "clang/Basic/OperatorKinds.def"
166 };
167 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
168 assert(OpName && "not an overloaded operator");
169
170 OS << "operator";
171 if (OpName[0] >= 'a' && OpName[0] <= 'z')
172 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000173 OS << OpName;
174 return;
David Blaikied4da8722013-05-14 21:04:00 +0000175 }
176
177 case DeclarationName::CXXLiteralOperatorName:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000178 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
179 return;
David Blaikied4da8722013-05-14 21:04:00 +0000180
181 case DeclarationName::CXXConversionFunctionName: {
182 OS << "operator ";
183 QualType Type = N.getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000184 if (const RecordType *Rec = Type->getAs<RecordType>()) {
185 OS << *Rec->getDecl();
186 return;
187 }
Richard Smith301bc212016-05-19 01:39:10 +0000188 // We know we're printing C++ here, ensure we print 'bool' properly.
189 PrintingPolicy CXXPolicy = Policy;
190 CXXPolicy.adjustForCPlusPlus();
191 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000192 return;
David Blaikied4da8722013-05-14 21:04:00 +0000193 }
194 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000195 OS << "<using-directive>";
196 return;
David Blaikied4da8722013-05-14 21:04:00 +0000197 }
198
199 llvm_unreachable("Unexpected declaration name kind");
200}
201
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000202namespace clang {
203
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000204raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
205 LangOptions LO;
206 N.print(OS, PrintingPolicy(LO));
207 return OS;
208}
209
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000210} // namespace clang
Douglas Gregor77324f32008-11-17 14:58:09 +0000211
Douglas Gregor77324f32008-11-17 14:58:09 +0000212DeclarationName::NameKind DeclarationName::getNameKind() const {
213 switch (getStoredNameKind()) {
214 case StoredIdentifier: return Identifier;
215 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
216 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
217
Douglas Gregor163c5852008-11-18 14:39:36 +0000218 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000219 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000220 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000221 return CXXConstructorName;
222
Mike Stump11289f42009-09-09 15:08:12 +0000223 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000224 return CXXDestructorName;
225
Richard Smith35845152017-02-07 01:37:30 +0000226 case DeclarationNameExtra::CXXDeductionGuide:
227 return CXXDeductionGuideName;
228
Mike Stump11289f42009-09-09 15:08:12 +0000229 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000230 return CXXConversionFunctionName;
231
Alexis Hunt3d221f22009-11-29 07:34:05 +0000232 case DeclarationNameExtra::CXXLiteralOperator:
233 return CXXLiteralOperatorName;
234
Douglas Gregor889ceb72009-02-03 19:21:40 +0000235 case DeclarationNameExtra::CXXUsingDirective:
236 return CXXUsingDirective;
237
Douglas Gregor77324f32008-11-17 14:58:09 +0000238 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000239 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000240 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000241 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000242 return CXXOperatorName;
243
Douglas Gregor77324f32008-11-17 14:58:09 +0000244 return ObjCMultiArgSelector;
245 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000246 }
247
248 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000249 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000250}
251
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000252bool DeclarationName::isDependentName() const {
253 QualType T = getCXXNameType();
Richard Smith35845152017-02-07 01:37:30 +0000254 if (!T.isNull() && T->isDependentType())
255 return true;
256
257 // A class-scope deduction guide in a dependent context has a dependent name.
258 auto *TD = getCXXDeductionGuideTemplate();
259 if (TD && TD->getDeclContext()->isDependentContext())
260 return true;
261
262 return false;
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000263}
264
Douglas Gregor92751d42008-11-17 22:58:34 +0000265std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000266 std::string Result;
267 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000268 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000269 return OS.str();
270}
271
Douglas Gregor77324f32008-11-17 14:58:09 +0000272QualType DeclarationName::getCXXNameType() const {
273 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
274 return CXXName->Type;
275 else
276 return QualType();
277}
278
Richard Smith35845152017-02-07 01:37:30 +0000279TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const {
280 if (auto *Guide = getAsCXXDeductionGuideNameExtra())
281 return Guide->Template;
282 return nullptr;
283}
284
Douglas Gregor163c5852008-11-18 14:39:36 +0000285OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
286 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000287 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000288 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
289 return static_cast<OverloadedOperatorKind>(value);
290 } else {
291 return OO_None;
292 }
293}
294
Alexis Hunt3d221f22009-11-29 07:34:05 +0000295IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
296 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
297 return CXXLit->ID;
298 else
Craig Topper36250ad2014-05-12 05:36:57 +0000299 return nullptr;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000300}
301
Douglas Gregor0da53052012-05-03 23:18:44 +0000302void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000303 switch (getNameKind()) {
304 case Identifier:
Benjamin Kramer1458c1c2012-05-19 16:03:58 +0000305 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000306
307 case CXXConstructorName:
308 case CXXDestructorName:
309 case CXXConversionFunctionName:
310 return getAsCXXSpecialName()->FETokenInfo;
311
Richard Smith35845152017-02-07 01:37:30 +0000312 case CXXDeductionGuideName:
313 return getAsCXXDeductionGuideNameExtra()->FETokenInfo;
314
Douglas Gregor163c5852008-11-18 14:39:36 +0000315 case CXXOperatorName:
316 return getAsCXXOperatorIdName()->FETokenInfo;
317
Alexis Hunt3d221f22009-11-29 07:34:05 +0000318 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000319 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000320
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000321 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000322 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000323 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000324}
325
326void DeclarationName::setFETokenInfo(void *T) {
327 switch (getNameKind()) {
328 case Identifier:
329 getAsIdentifierInfo()->setFETokenInfo(T);
330 break;
331
332 case CXXConstructorName:
333 case CXXDestructorName:
334 case CXXConversionFunctionName:
335 getAsCXXSpecialName()->FETokenInfo = T;
336 break;
337
Richard Smith35845152017-02-07 01:37:30 +0000338 case CXXDeductionGuideName:
339 getAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
340 break;
341
Douglas Gregor163c5852008-11-18 14:39:36 +0000342 case CXXOperatorName:
343 getAsCXXOperatorIdName()->FETokenInfo = T;
344 break;
345
Alexis Hunt3d221f22009-11-29 07:34:05 +0000346 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000347 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000348 break;
349
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000350 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000351 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000352 }
353}
354
Douglas Gregor889ceb72009-02-03 19:21:40 +0000355DeclarationName DeclarationName::getUsingDirectiveName() {
356 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000357 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000358 { DeclarationNameExtra::CXXUsingDirective };
359
360 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
361 Ptr |= StoredDeclarationNameExtra;
362
363 return DeclarationName(Ptr);
364}
365
Yaron Kerencdae9412016-01-29 19:38:18 +0000366LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000367 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000368}
369
Jay Foad39c79802011-01-12 09:06:06 +0000370DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor163c5852008-11-18 14:39:36 +0000371 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000372 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000373 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000374 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000375 = Op + DeclarationNameExtra::CXXConversionFunction;
Craig Topper36250ad2014-05-12 05:36:57 +0000376 CXXOperatorNames[Op].FETokenInfo = nullptr;
Douglas Gregor163c5852008-11-18 14:39:36 +0000377 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000378}
379
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000380DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
381 return getCXXSpecialName(DeclarationName::CXXConstructorName,
382 Ty.getUnqualifiedType());
383}
384
385DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
386 return getCXXSpecialName(DeclarationName::CXXDestructorName,
387 Ty.getUnqualifiedType());
388}
389
390DeclarationName
Richard Smith35845152017-02-07 01:37:30 +0000391DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
392 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
393
Richard Smith35845152017-02-07 01:37:30 +0000394 llvm::FoldingSetNodeID ID;
395 ID.AddPointer(Template);
396
397 void *InsertPos = nullptr;
Bruno Riccib6198832018-08-06 16:47:31 +0000398 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
Richard Smith35845152017-02-07 01:37:30 +0000399 return DeclarationName(Name);
400
401 auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
402 Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
403 Name->Template = Template;
404 Name->FETokenInfo = nullptr;
405
Bruno Riccib6198832018-08-06 16:47:31 +0000406 CXXDeductionGuideNames.InsertNode(Name, InsertPos);
Richard Smith35845152017-02-07 01:37:30 +0000407 return DeclarationName(Name);
408}
409
410DeclarationName
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000411DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
412 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
413}
414
Mike Stump11289f42009-09-09 15:08:12 +0000415DeclarationName
416DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000417 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000418 assert(Kind >= DeclarationName::CXXConstructorName &&
419 Kind <= DeclarationName::CXXConversionFunctionName &&
420 "Kind must be a C++ special name kind");
Douglas Gregor77324f32008-11-17 14:58:09 +0000421
422 DeclarationNameExtra::ExtraKind EKind;
423 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000424 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000425 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000426 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000427 break;
428 case DeclarationName::CXXDestructorName:
429 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000430 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000431 break;
432 case DeclarationName::CXXConversionFunctionName:
433 EKind = DeclarationNameExtra::CXXConversionFunction;
434 break;
435 default:
436 return DeclarationName();
437 }
438
439 // Unique selector, to guarantee there is one per name.
440 llvm::FoldingSetNodeID ID;
441 ID.AddInteger(EKind);
442 ID.AddPointer(Ty.getAsOpaquePtr());
443
Craig Topper36250ad2014-05-12 05:36:57 +0000444 void *InsertPos = nullptr;
Bruno Riccib6198832018-08-06 16:47:31 +0000445 if (CXXSpecialName *Name = CXXSpecialNames.FindNodeOrInsertPos(ID, InsertPos))
Douglas Gregor77324f32008-11-17 14:58:09 +0000446 return DeclarationName(Name);
447
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000448 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000449 SpecialName->ExtraKindOrNumArgs = EKind;
450 SpecialName->Type = Ty;
Craig Topper36250ad2014-05-12 05:36:57 +0000451 SpecialName->FETokenInfo = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000452
Bruno Riccib6198832018-08-06 16:47:31 +0000453 CXXSpecialNames.InsertNode(SpecialName, InsertPos);
Douglas Gregor77324f32008-11-17 14:58:09 +0000454 return DeclarationName(SpecialName);
455}
456
Mike Stump11289f42009-09-09 15:08:12 +0000457DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000458DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
459 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
460}
461
Alexis Hunt3d221f22009-11-29 07:34:05 +0000462DeclarationName
463DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000464 llvm::FoldingSetNodeID ID;
465 ID.AddPointer(II);
466
Craig Topper36250ad2014-05-12 05:36:57 +0000467 void *InsertPos = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000468 if (CXXLiteralOperatorIdName *Name =
Bruno Riccib6198832018-08-06 16:47:31 +0000469 CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
Alexis Huntc88db062010-01-13 09:01:02 +0000470 return DeclarationName (Name);
Fangrui Song6907ce22018-07-30 19:24:48 +0000471
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000472 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000473 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
474 LiteralName->ID = II;
Craig Topper36250ad2014-05-12 05:36:57 +0000475 LiteralName->FETokenInfo = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000476
Bruno Riccib6198832018-08-06 16:47:31 +0000477 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000478 return DeclarationName(LiteralName);
479}
480
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000481DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
482 switch (Name.getNameKind()) {
483 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000484 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000485 break;
486 case DeclarationName::CXXConstructorName:
487 case DeclarationName::CXXDestructorName:
488 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000489 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000490 break;
491 case DeclarationName::CXXOperatorName:
492 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
493 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
494 break;
495 case DeclarationName::CXXLiteralOperatorName:
496 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
497 break;
498 case DeclarationName::ObjCZeroArgSelector:
499 case DeclarationName::ObjCOneArgSelector:
500 case DeclarationName::ObjCMultiArgSelector:
501 // FIXME: ?
502 break;
503 case DeclarationName::CXXUsingDirective:
504 break;
505 }
506}
507
Douglas Gregora6e053e2010-12-15 01:34:56 +0000508bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
509 switch (Name.getNameKind()) {
510 case DeclarationName::Identifier:
511 case DeclarationName::ObjCZeroArgSelector:
512 case DeclarationName::ObjCOneArgSelector:
513 case DeclarationName::ObjCMultiArgSelector:
514 case DeclarationName::CXXOperatorName:
515 case DeclarationName::CXXLiteralOperatorName:
516 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000517 case DeclarationName::CXXDeductionGuideName:
Douglas Gregora6e053e2010-12-15 01:34:56 +0000518 return false;
519
520 case DeclarationName::CXXConstructorName:
521 case DeclarationName::CXXDestructorName:
522 case DeclarationName::CXXConversionFunctionName:
523 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
524 return TInfo->getType()->containsUnexpandedParameterPack();
525
526 return Name.getCXXNameType()->containsUnexpandedParameterPack();
527 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000528 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000529}
530
Douglas Gregor678d76c2011-07-01 01:22:09 +0000531bool DeclarationNameInfo::isInstantiationDependent() const {
532 switch (Name.getNameKind()) {
533 case DeclarationName::Identifier:
534 case DeclarationName::ObjCZeroArgSelector:
535 case DeclarationName::ObjCOneArgSelector:
536 case DeclarationName::ObjCMultiArgSelector:
537 case DeclarationName::CXXOperatorName:
538 case DeclarationName::CXXLiteralOperatorName:
539 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000540 case DeclarationName::CXXDeductionGuideName:
Douglas Gregor678d76c2011-07-01 01:22:09 +0000541 return false;
Fangrui Song6907ce22018-07-30 19:24:48 +0000542
Douglas Gregor678d76c2011-07-01 01:22:09 +0000543 case DeclarationName::CXXConstructorName:
544 case DeclarationName::CXXDestructorName:
545 case DeclarationName::CXXConversionFunctionName:
546 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
547 return TInfo->getType()->isInstantiationDependentType();
Fangrui Song6907ce22018-07-30 19:24:48 +0000548
Douglas Gregor678d76c2011-07-01 01:22:09 +0000549 return Name.getCXXNameType()->isInstantiationDependentType();
550 }
551 llvm_unreachable("All name kinds handled.");
552}
553
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000554std::string DeclarationNameInfo::getAsString() const {
555 std::string Result;
556 llvm::raw_string_ostream OS(Result);
557 printName(OS);
558 return OS.str();
559}
560
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000561void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000562 switch (Name.getNameKind()) {
563 case DeclarationName::Identifier:
564 case DeclarationName::ObjCZeroArgSelector:
565 case DeclarationName::ObjCOneArgSelector:
566 case DeclarationName::ObjCMultiArgSelector:
567 case DeclarationName::CXXOperatorName:
568 case DeclarationName::CXXLiteralOperatorName:
569 case DeclarationName::CXXUsingDirective:
Richard Smith35845152017-02-07 01:37:30 +0000570 case DeclarationName::CXXDeductionGuideName:
David Blaikied4da8722013-05-14 21:04:00 +0000571 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000572 return;
573
574 case DeclarationName::CXXConstructorName:
575 case DeclarationName::CXXDestructorName:
576 case DeclarationName::CXXConversionFunctionName:
577 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
578 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
579 OS << '~';
580 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
581 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000582 LangOptions LO;
583 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000584 LO.Bool = true;
Alex Lorenza981c7d2017-04-11 16:46:03 +0000585 PrintingPolicy PP(LO);
586 PP.SuppressScope = true;
587 OS << TInfo->getType().getAsString(PP);
David Blaikied4da8722013-05-14 21:04:00 +0000588 } else
589 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000590 return;
591 }
David Blaikie83d382b2011-09-23 05:06:16 +0000592 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000593}
594
Stephen Kellyf50288c2018-07-30 20:39:14 +0000595SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000596 switch (Name.getNameKind()) {
597 case DeclarationName::Identifier:
Richard Smith35845152017-02-07 01:37:30 +0000598 case DeclarationName::CXXDeductionGuideName:
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000599 return NameLoc;
600
601 case DeclarationName::CXXOperatorName: {
602 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
603 return SourceLocation::getFromRawEncoding(raw);
604 }
605
606 case DeclarationName::CXXLiteralOperatorName: {
607 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
608 return SourceLocation::getFromRawEncoding(raw);
609 }
610
611 case DeclarationName::CXXConstructorName:
612 case DeclarationName::CXXDestructorName:
613 case DeclarationName::CXXConversionFunctionName:
614 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
615 return TInfo->getTypeLoc().getEndLoc();
616 else
617 return NameLoc;
618
619 // DNInfo work in progress: FIXME.
620 case DeclarationName::ObjCZeroArgSelector:
621 case DeclarationName::ObjCOneArgSelector:
622 case DeclarationName::ObjCMultiArgSelector:
623 case DeclarationName::CXXUsingDirective:
624 return NameLoc;
625 }
David Blaikie83d382b2011-09-23 05:06:16 +0000626 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000627}