blob: fea887e1738b73318823dd080ccc8c819e4cca49 [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"
Douglas Gregor92751d42008-11-17 22:58:34 +000017#include "clang/AST/Type.h"
Abramo Bagnarad6d2f182010-08-11 22:01:17 +000018#include "clang/AST/TypeLoc.h"
Douglas Gregorb082bab2009-11-04 22:24:30 +000019#include "clang/AST/TypeOrdering.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000020#include "clang/Basic/IdentifierTable.h"
21#include "llvm/ADT/FoldingSet.h"
Chandler Carruth2b59fbe2010-12-15 07:29:18 +000022#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer95c7c422010-04-17 09:56:45 +000023#include "llvm/Support/raw_ostream.h"
Douglas Gregor77324f32008-11-17 14:58:09 +000024using namespace clang;
25
26namespace clang {
27/// CXXSpecialName - Records the type associated with one of the
28/// "special" kinds of declaration names in C++, e.g., constructors,
29/// destructors, and conversion functions.
Mike Stump11289f42009-09-09 15:08:12 +000030class CXXSpecialName
Douglas Gregor77324f32008-11-17 14:58:09 +000031 : public DeclarationNameExtra, public llvm::FoldingSetNode {
32public:
Douglas Gregorae2fbad2008-11-17 20:34:05 +000033 /// Type - The type associated with this declaration name.
Douglas Gregor77324f32008-11-17 14:58:09 +000034 QualType Type;
35
Douglas Gregorae2fbad2008-11-17 20:34:05 +000036 /// FETokenInfo - Extra information associated with this declaration
37 /// name that can be used by the front end.
38 void *FETokenInfo;
39
Douglas Gregor77324f32008-11-17 14:58:09 +000040 void Profile(llvm::FoldingSetNodeID &ID) {
41 ID.AddInteger(ExtraKindOrNumArgs);
42 ID.AddPointer(Type.getAsOpaquePtr());
43 }
44};
45
Douglas Gregor163c5852008-11-18 14:39:36 +000046/// CXXOperatorIdName - Contains extra information for the name of an
Mike Stump11289f42009-09-09 15:08:12 +000047/// overloaded operator in C++, such as "operator+.
Douglas Gregor163c5852008-11-18 14:39:36 +000048class CXXOperatorIdName : public DeclarationNameExtra {
49public:
50 /// FETokenInfo - Extra information associated with this operator
51 /// name that can be used by the front end.
52 void *FETokenInfo;
53};
54
Richard Smithc1b05652012-03-09 08:37:16 +000055/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
Alexis Hunt3d221f22009-11-29 07:34:05 +000056/// name.
57///
58/// This identifier is stored here rather than directly in DeclarationName so as
59/// to allow Objective-C selectors, which are about a million times more common,
60/// to consume minimal memory.
Alexis Huntc88db062010-01-13 09:01:02 +000061class CXXLiteralOperatorIdName
62 : public DeclarationNameExtra, public llvm::FoldingSetNode {
Alexis Hunt3d221f22009-11-29 07:34:05 +000063public:
64 IdentifierInfo *ID;
Alexis Huntc88db062010-01-13 09:01:02 +000065
Richard Smithc1b05652012-03-09 08:37:16 +000066 /// FETokenInfo - Extra information associated with this operator
67 /// name that can be used by the front end.
68 void *FETokenInfo;
69
Alexis Huntc88db062010-01-13 09:01:02 +000070 void Profile(llvm::FoldingSetNodeID &FSID) {
71 FSID.AddPointer(ID);
72 }
Alexis Hunt3d221f22009-11-29 07:34:05 +000073};
74
John McCallef3057c2010-02-13 01:04:05 +000075static int compareInt(unsigned A, unsigned B) {
76 return (A < B ? -1 : (A > B ? 1 : 0));
77}
78
79int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
Douglas Gregorb082bab2009-11-04 22:24:30 +000080 if (LHS.getNameKind() != RHS.getNameKind())
John McCallef3057c2010-02-13 01:04:05 +000081 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
Douglas Gregorb082bab2009-11-04 22:24:30 +000082
83 switch (LHS.getNameKind()) {
John McCallef3057c2010-02-13 01:04:05 +000084 case DeclarationName::Identifier: {
85 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
86 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
87 if (!LII) return RII ? -1 : 0;
88 if (!RII) return 1;
89
90 return LII->getName().compare(RII->getName());
91 }
Douglas Gregor77324f32008-11-17 14:58:09 +000092
Douglas Gregorb082bab2009-11-04 22:24:30 +000093 case DeclarationName::ObjCZeroArgSelector:
94 case DeclarationName::ObjCOneArgSelector:
95 case DeclarationName::ObjCMultiArgSelector: {
96 Selector LHSSelector = LHS.getObjCSelector();
97 Selector RHSSelector = RHS.getObjCSelector();
John McCallef3057c2010-02-13 01:04:05 +000098 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
99 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +0000100 switch (LHSSelector.getNameForSlot(I).compare(
101 RHSSelector.getNameForSlot(I))) {
Douglas Gregorb082bab2009-11-04 22:24:30 +0000102 case -1: return true;
103 case 1: return false;
104 default: break;
105 }
106 }
John McCallef3057c2010-02-13 01:04:05 +0000107
108 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +0000109 }
110
111 case DeclarationName::CXXConstructorName:
112 case DeclarationName::CXXDestructorName:
113 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +0000114 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
115 return -1;
116 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
117 return 1;
118 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000119
120 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000121 return compareInt(LHS.getCXXOverloadedOperator(),
122 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000123
124 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000125 return LHS.getCXXLiteralIdentifier()->getName().compare(
126 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregorb082bab2009-11-04 22:24:30 +0000127
128 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000129 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000130 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000131
132 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000133}
134
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000135static void printCXXConstructorDestructorName(QualType ClassType,
136 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000137 PrintingPolicy Policy) {
138 // We know we're printing C++ here. Ensure we print types properly.
139 Policy.adjustForCPlusPlus();
140
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000141 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
142 OS << *ClassRec->getDecl();
143 return;
144 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000145 if (Policy.SuppressTemplateArgsInCXXConstructors) {
146 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
147 OS << *InjTy->getDecl();
148 return;
149 }
150 }
Richard Smith301bc212016-05-19 01:39:10 +0000151 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000152}
153
154void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
155 DeclarationName &N = *this;
David Blaikied4da8722013-05-14 21:04:00 +0000156 switch (N.getNameKind()) {
157 case DeclarationName::Identifier:
158 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
159 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000160 return;
David Blaikied4da8722013-05-14 21:04:00 +0000161
162 case DeclarationName::ObjCZeroArgSelector:
163 case DeclarationName::ObjCOneArgSelector:
164 case DeclarationName::ObjCMultiArgSelector:
Aaron Ballmanb190f972014-01-03 17:59:55 +0000165 N.getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000166 return;
David Blaikied4da8722013-05-14 21:04:00 +0000167
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000168 case DeclarationName::CXXConstructorName:
169 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000170
171 case DeclarationName::CXXDestructorName: {
172 OS << '~';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000173 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000174 }
175
176 case DeclarationName::CXXOperatorName: {
177 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Craig Topper36250ad2014-05-12 05:36:57 +0000178 nullptr,
David Blaikied4da8722013-05-14 21:04:00 +0000179#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
180 Spelling,
181#include "clang/Basic/OperatorKinds.def"
182 };
183 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
184 assert(OpName && "not an overloaded operator");
185
186 OS << "operator";
187 if (OpName[0] >= 'a' && OpName[0] <= 'z')
188 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000189 OS << OpName;
190 return;
David Blaikied4da8722013-05-14 21:04:00 +0000191 }
192
193 case DeclarationName::CXXLiteralOperatorName:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000194 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
195 return;
David Blaikied4da8722013-05-14 21:04:00 +0000196
197 case DeclarationName::CXXConversionFunctionName: {
198 OS << "operator ";
199 QualType Type = N.getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000200 if (const RecordType *Rec = Type->getAs<RecordType>()) {
201 OS << *Rec->getDecl();
202 return;
203 }
Richard Smith301bc212016-05-19 01:39:10 +0000204 // We know we're printing C++ here, ensure we print 'bool' properly.
205 PrintingPolicy CXXPolicy = Policy;
206 CXXPolicy.adjustForCPlusPlus();
207 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000208 return;
David Blaikied4da8722013-05-14 21:04:00 +0000209 }
210 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000211 OS << "<using-directive>";
212 return;
David Blaikied4da8722013-05-14 21:04:00 +0000213 }
214
215 llvm_unreachable("Unexpected declaration name kind");
216}
217
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000218raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
219 LangOptions LO;
220 N.print(OS, PrintingPolicy(LO));
221 return OS;
222}
223
Douglas Gregor77324f32008-11-17 14:58:09 +0000224} // end namespace clang
225
Douglas Gregor77324f32008-11-17 14:58:09 +0000226DeclarationName::NameKind DeclarationName::getNameKind() const {
227 switch (getStoredNameKind()) {
228 case StoredIdentifier: return Identifier;
229 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
230 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
231
Douglas Gregor163c5852008-11-18 14:39:36 +0000232 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000233 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000234 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000235 return CXXConstructorName;
236
Mike Stump11289f42009-09-09 15:08:12 +0000237 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000238 return CXXDestructorName;
239
Mike Stump11289f42009-09-09 15:08:12 +0000240 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000241 return CXXConversionFunctionName;
242
Alexis Hunt3d221f22009-11-29 07:34:05 +0000243 case DeclarationNameExtra::CXXLiteralOperator:
244 return CXXLiteralOperatorName;
245
Douglas Gregor889ceb72009-02-03 19:21:40 +0000246 case DeclarationNameExtra::CXXUsingDirective:
247 return CXXUsingDirective;
248
Douglas Gregor77324f32008-11-17 14:58:09 +0000249 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000250 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000251 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000252 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000253 return CXXOperatorName;
254
Douglas Gregor77324f32008-11-17 14:58:09 +0000255 return ObjCMultiArgSelector;
256 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000257 }
258
259 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000260 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000261}
262
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000263bool DeclarationName::isDependentName() const {
264 QualType T = getCXXNameType();
265 return !T.isNull() && T->isDependentType();
266}
267
Douglas Gregor92751d42008-11-17 22:58:34 +0000268std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000269 std::string Result;
270 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000271 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000272 return OS.str();
273}
274
Douglas Gregor77324f32008-11-17 14:58:09 +0000275QualType DeclarationName::getCXXNameType() const {
276 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
277 return CXXName->Type;
278 else
279 return QualType();
280}
281
Douglas Gregor163c5852008-11-18 14:39:36 +0000282OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
283 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000284 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000285 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
286 return static_cast<OverloadedOperatorKind>(value);
287 } else {
288 return OO_None;
289 }
290}
291
Alexis Hunt3d221f22009-11-29 07:34:05 +0000292IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
293 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
294 return CXXLit->ID;
295 else
Craig Topper36250ad2014-05-12 05:36:57 +0000296 return nullptr;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000297}
298
Douglas Gregor0da53052012-05-03 23:18:44 +0000299void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000300 switch (getNameKind()) {
301 case Identifier:
Benjamin Kramer1458c1c2012-05-19 16:03:58 +0000302 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000303
304 case CXXConstructorName:
305 case CXXDestructorName:
306 case CXXConversionFunctionName:
307 return getAsCXXSpecialName()->FETokenInfo;
308
Douglas Gregor163c5852008-11-18 14:39:36 +0000309 case CXXOperatorName:
310 return getAsCXXOperatorIdName()->FETokenInfo;
311
Alexis Hunt3d221f22009-11-29 07:34:05 +0000312 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000313 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000314
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000315 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000316 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000317 }
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000318}
319
320void DeclarationName::setFETokenInfo(void *T) {
321 switch (getNameKind()) {
322 case Identifier:
323 getAsIdentifierInfo()->setFETokenInfo(T);
324 break;
325
326 case CXXConstructorName:
327 case CXXDestructorName:
328 case CXXConversionFunctionName:
329 getAsCXXSpecialName()->FETokenInfo = T;
330 break;
331
Douglas Gregor163c5852008-11-18 14:39:36 +0000332 case CXXOperatorName:
333 getAsCXXOperatorIdName()->FETokenInfo = T;
334 break;
335
Alexis Hunt3d221f22009-11-29 07:34:05 +0000336 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000337 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000338 break;
339
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000340 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000341 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000342 }
343}
344
Douglas Gregor889ceb72009-02-03 19:21:40 +0000345DeclarationName DeclarationName::getUsingDirectiveName() {
346 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000347 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000348 { DeclarationNameExtra::CXXUsingDirective };
349
350 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
351 Ptr |= StoredDeclarationNameExtra;
352
353 return DeclarationName(Ptr);
354}
355
Yaron Kerencdae9412016-01-29 19:38:18 +0000356LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000357 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000358}
359
Jay Foad39c79802011-01-12 09:06:06 +0000360DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000361 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Alexis Huntc88db062010-01-13 09:01:02 +0000362 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregor163c5852008-11-18 14:39:36 +0000363
364 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000365 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000366 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000367 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000368 = Op + DeclarationNameExtra::CXXConversionFunction;
Craig Topper36250ad2014-05-12 05:36:57 +0000369 CXXOperatorNames[Op].FETokenInfo = nullptr;
Douglas Gregor163c5852008-11-18 14:39:36 +0000370 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000371}
372
373DeclarationNameTable::~DeclarationNameTable() {
Alexis Huntc88db062010-01-13 09:01:02 +0000374 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes127adb42008-12-14 17:27:25 +0000375 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Alexis Huntc88db062010-01-13 09:01:02 +0000376 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
377 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000378 (CXXLiteralOperatorNames);
Alexis Huntc88db062010-01-13 09:01:02 +0000379
Alexis Huntc88db062010-01-13 09:01:02 +0000380 delete SpecialNames;
381 delete LiteralNames;
Ted Kremenek6aead3a2010-05-10 20:40:08 +0000382}
383
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000384DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
385 return getCXXSpecialName(DeclarationName::CXXConstructorName,
386 Ty.getUnqualifiedType());
387}
388
389DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
390 return getCXXSpecialName(DeclarationName::CXXDestructorName,
391 Ty.getUnqualifiedType());
392}
393
394DeclarationName
395DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
396 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
397}
398
Mike Stump11289f42009-09-09 15:08:12 +0000399DeclarationName
400DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000401 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000402 assert(Kind >= DeclarationName::CXXConstructorName &&
403 Kind <= DeclarationName::CXXConversionFunctionName &&
404 "Kind must be a C++ special name kind");
Mike Stump11289f42009-09-09 15:08:12 +0000405 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor77324f32008-11-17 14:58:09 +0000406 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
407
408 DeclarationNameExtra::ExtraKind EKind;
409 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000410 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000411 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000412 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000413 break;
414 case DeclarationName::CXXDestructorName:
415 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000416 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000417 break;
418 case DeclarationName::CXXConversionFunctionName:
419 EKind = DeclarationNameExtra::CXXConversionFunction;
420 break;
421 default:
422 return DeclarationName();
423 }
424
425 // Unique selector, to guarantee there is one per name.
426 llvm::FoldingSetNodeID ID;
427 ID.AddInteger(EKind);
428 ID.AddPointer(Ty.getAsOpaquePtr());
429
Craig Topper36250ad2014-05-12 05:36:57 +0000430 void *InsertPos = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000431 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
432 return DeclarationName(Name);
433
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000434 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000435 SpecialName->ExtraKindOrNumArgs = EKind;
436 SpecialName->Type = Ty;
Craig Topper36250ad2014-05-12 05:36:57 +0000437 SpecialName->FETokenInfo = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000438
439 SpecialNames->InsertNode(SpecialName, InsertPos);
440 return DeclarationName(SpecialName);
441}
442
Mike Stump11289f42009-09-09 15:08:12 +0000443DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000444DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
445 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
446}
447
Alexis Hunt3d221f22009-11-29 07:34:05 +0000448DeclarationName
449DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000450 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
451 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
452 (CXXLiteralOperatorNames);
453
454 llvm::FoldingSetNodeID ID;
455 ID.AddPointer(II);
456
Craig Topper36250ad2014-05-12 05:36:57 +0000457 void *InsertPos = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000458 if (CXXLiteralOperatorIdName *Name =
459 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
460 return DeclarationName (Name);
461
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000462 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000463 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
464 LiteralName->ID = II;
Craig Topper36250ad2014-05-12 05:36:57 +0000465 LiteralName->FETokenInfo = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000466
467 LiteralNames->InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000468 return DeclarationName(LiteralName);
469}
470
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000471DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
472 switch (Name.getNameKind()) {
473 case DeclarationName::Identifier:
474 break;
475 case DeclarationName::CXXConstructorName:
476 case DeclarationName::CXXDestructorName:
477 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000478 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000479 break;
480 case DeclarationName::CXXOperatorName:
481 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
482 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
483 break;
484 case DeclarationName::CXXLiteralOperatorName:
485 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
486 break;
487 case DeclarationName::ObjCZeroArgSelector:
488 case DeclarationName::ObjCOneArgSelector:
489 case DeclarationName::ObjCMultiArgSelector:
490 // FIXME: ?
491 break;
492 case DeclarationName::CXXUsingDirective:
493 break;
494 }
495}
496
Douglas Gregora6e053e2010-12-15 01:34:56 +0000497bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
498 switch (Name.getNameKind()) {
499 case DeclarationName::Identifier:
500 case DeclarationName::ObjCZeroArgSelector:
501 case DeclarationName::ObjCOneArgSelector:
502 case DeclarationName::ObjCMultiArgSelector:
503 case DeclarationName::CXXOperatorName:
504 case DeclarationName::CXXLiteralOperatorName:
505 case DeclarationName::CXXUsingDirective:
506 return false;
507
508 case DeclarationName::CXXConstructorName:
509 case DeclarationName::CXXDestructorName:
510 case DeclarationName::CXXConversionFunctionName:
511 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
512 return TInfo->getType()->containsUnexpandedParameterPack();
513
514 return Name.getCXXNameType()->containsUnexpandedParameterPack();
515 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000516 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000517}
518
Douglas Gregor678d76c2011-07-01 01:22:09 +0000519bool DeclarationNameInfo::isInstantiationDependent() const {
520 switch (Name.getNameKind()) {
521 case DeclarationName::Identifier:
522 case DeclarationName::ObjCZeroArgSelector:
523 case DeclarationName::ObjCOneArgSelector:
524 case DeclarationName::ObjCMultiArgSelector:
525 case DeclarationName::CXXOperatorName:
526 case DeclarationName::CXXLiteralOperatorName:
527 case DeclarationName::CXXUsingDirective:
528 return false;
529
530 case DeclarationName::CXXConstructorName:
531 case DeclarationName::CXXDestructorName:
532 case DeclarationName::CXXConversionFunctionName:
533 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
534 return TInfo->getType()->isInstantiationDependentType();
535
536 return Name.getCXXNameType()->isInstantiationDependentType();
537 }
538 llvm_unreachable("All name kinds handled.");
539}
540
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000541std::string DeclarationNameInfo::getAsString() const {
542 std::string Result;
543 llvm::raw_string_ostream OS(Result);
544 printName(OS);
545 return OS.str();
546}
547
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000548void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000549 switch (Name.getNameKind()) {
550 case DeclarationName::Identifier:
551 case DeclarationName::ObjCZeroArgSelector:
552 case DeclarationName::ObjCOneArgSelector:
553 case DeclarationName::ObjCMultiArgSelector:
554 case DeclarationName::CXXOperatorName:
555 case DeclarationName::CXXLiteralOperatorName:
556 case DeclarationName::CXXUsingDirective:
David Blaikied4da8722013-05-14 21:04:00 +0000557 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000558 return;
559
560 case DeclarationName::CXXConstructorName:
561 case DeclarationName::CXXDestructorName:
562 case DeclarationName::CXXConversionFunctionName:
563 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
564 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
565 OS << '~';
566 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
567 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000568 LangOptions LO;
569 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000570 LO.Bool = true;
Richard Smithe81daee2014-01-22 00:27:42 +0000571 OS << TInfo->getType().getAsString(PrintingPolicy(LO));
David Blaikied4da8722013-05-14 21:04:00 +0000572 } else
573 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000574 return;
575 }
David Blaikie83d382b2011-09-23 05:06:16 +0000576 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000577}
578
579SourceLocation DeclarationNameInfo::getEndLoc() const {
580 switch (Name.getNameKind()) {
581 case DeclarationName::Identifier:
582 return NameLoc;
583
584 case DeclarationName::CXXOperatorName: {
585 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
586 return SourceLocation::getFromRawEncoding(raw);
587 }
588
589 case DeclarationName::CXXLiteralOperatorName: {
590 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
591 return SourceLocation::getFromRawEncoding(raw);
592 }
593
594 case DeclarationName::CXXConstructorName:
595 case DeclarationName::CXXDestructorName:
596 case DeclarationName::CXXConversionFunctionName:
597 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
598 return TInfo->getTypeLoc().getEndLoc();
599 else
600 return NameLoc;
601
602 // DNInfo work in progress: FIXME.
603 case DeclarationName::ObjCZeroArgSelector:
604 case DeclarationName::ObjCOneArgSelector:
605 case DeclarationName::ObjCMultiArgSelector:
606 case DeclarationName::CXXUsingDirective:
607 return NameLoc;
608 }
David Blaikie83d382b2011-09-23 05:06:16 +0000609 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000610}