blob: 52791e51d2dc1271db55d5534dc214e76a63c1d1 [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();
Manman Renb6665732016-11-17 18:41:18 +000098 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
99 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
100 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
101 return LHSSelector.getAsIdentifierInfo()->getName().compare(
102 RHSSelector.getAsIdentifierInfo()->getName());
103 }
John McCallef3057c2010-02-13 01:04:05 +0000104 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
105 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
Douglas Gregoraf2a6ae2011-02-18 22:29:55 +0000106 switch (LHSSelector.getNameForSlot(I).compare(
107 RHSSelector.getNameForSlot(I))) {
Manman Renb6665732016-11-17 18:41:18 +0000108 case -1: return -1;
109 case 1: return 1;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000110 default: break;
111 }
112 }
John McCallef3057c2010-02-13 01:04:05 +0000113
114 return compareInt(LN, RN);
Douglas Gregorb082bab2009-11-04 22:24:30 +0000115 }
116
117 case DeclarationName::CXXConstructorName:
118 case DeclarationName::CXXDestructorName:
119 case DeclarationName::CXXConversionFunctionName:
John McCallef3057c2010-02-13 01:04:05 +0000120 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
121 return -1;
122 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
123 return 1;
124 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000125
126 case DeclarationName::CXXOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000127 return compareInt(LHS.getCXXOverloadedOperator(),
128 RHS.getCXXOverloadedOperator());
Alexis Hunt3d221f22009-11-29 07:34:05 +0000129
130 case DeclarationName::CXXLiteralOperatorName:
John McCallef3057c2010-02-13 01:04:05 +0000131 return LHS.getCXXLiteralIdentifier()->getName().compare(
132 RHS.getCXXLiteralIdentifier()->getName());
Douglas Gregorb082bab2009-11-04 22:24:30 +0000133
134 case DeclarationName::CXXUsingDirective:
John McCallef3057c2010-02-13 01:04:05 +0000135 return 0;
Douglas Gregorb082bab2009-11-04 22:24:30 +0000136 }
David Blaikiee4d798f2012-01-20 21:50:17 +0000137
138 llvm_unreachable("Invalid DeclarationName Kind!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000139}
140
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000141static void printCXXConstructorDestructorName(QualType ClassType,
142 raw_ostream &OS,
Richard Smith301bc212016-05-19 01:39:10 +0000143 PrintingPolicy Policy) {
144 // We know we're printing C++ here. Ensure we print types properly.
145 Policy.adjustForCPlusPlus();
146
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000147 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
148 OS << *ClassRec->getDecl();
149 return;
150 }
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000151 if (Policy.SuppressTemplateArgsInCXXConstructors) {
152 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
153 OS << *InjTy->getDecl();
154 return;
155 }
156 }
Richard Smith301bc212016-05-19 01:39:10 +0000157 ClassType.print(OS, Policy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000158}
159
160void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
161 DeclarationName &N = *this;
David Blaikied4da8722013-05-14 21:04:00 +0000162 switch (N.getNameKind()) {
163 case DeclarationName::Identifier:
164 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
165 OS << II->getName();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000166 return;
David Blaikied4da8722013-05-14 21:04:00 +0000167
168 case DeclarationName::ObjCZeroArgSelector:
169 case DeclarationName::ObjCOneArgSelector:
170 case DeclarationName::ObjCMultiArgSelector:
Aaron Ballmanb190f972014-01-03 17:59:55 +0000171 N.getObjCSelector().print(OS);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000172 return;
David Blaikied4da8722013-05-14 21:04:00 +0000173
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000174 case DeclarationName::CXXConstructorName:
175 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000176
177 case DeclarationName::CXXDestructorName: {
178 OS << '~';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000179 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
David Blaikied4da8722013-05-14 21:04:00 +0000180 }
181
182 case DeclarationName::CXXOperatorName: {
183 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
Craig Topper36250ad2014-05-12 05:36:57 +0000184 nullptr,
David Blaikied4da8722013-05-14 21:04:00 +0000185#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
186 Spelling,
187#include "clang/Basic/OperatorKinds.def"
188 };
189 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
190 assert(OpName && "not an overloaded operator");
191
192 OS << "operator";
193 if (OpName[0] >= 'a' && OpName[0] <= 'z')
194 OS << ' ';
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000195 OS << OpName;
196 return;
David Blaikied4da8722013-05-14 21:04:00 +0000197 }
198
199 case DeclarationName::CXXLiteralOperatorName:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000200 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
201 return;
David Blaikied4da8722013-05-14 21:04:00 +0000202
203 case DeclarationName::CXXConversionFunctionName: {
204 OS << "operator ";
205 QualType Type = N.getCXXNameType();
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000206 if (const RecordType *Rec = Type->getAs<RecordType>()) {
207 OS << *Rec->getDecl();
208 return;
209 }
Richard Smith301bc212016-05-19 01:39:10 +0000210 // We know we're printing C++ here, ensure we print 'bool' properly.
211 PrintingPolicy CXXPolicy = Policy;
212 CXXPolicy.adjustForCPlusPlus();
213 Type.print(OS, CXXPolicy);
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000214 return;
David Blaikied4da8722013-05-14 21:04:00 +0000215 }
216 case DeclarationName::CXXUsingDirective:
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000217 OS << "<using-directive>";
218 return;
David Blaikied4da8722013-05-14 21:04:00 +0000219 }
220
221 llvm_unreachable("Unexpected declaration name kind");
222}
223
Argyrios Kyrtzidise91793c2016-02-13 21:46:50 +0000224raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
225 LangOptions LO;
226 N.print(OS, PrintingPolicy(LO));
227 return OS;
228}
229
Douglas Gregor77324f32008-11-17 14:58:09 +0000230} // end namespace clang
231
Douglas Gregor77324f32008-11-17 14:58:09 +0000232DeclarationName::NameKind DeclarationName::getNameKind() const {
233 switch (getStoredNameKind()) {
234 case StoredIdentifier: return Identifier;
235 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
236 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
237
Douglas Gregor163c5852008-11-18 14:39:36 +0000238 case StoredDeclarationNameExtra:
Douglas Gregor77324f32008-11-17 14:58:09 +0000239 switch (getExtra()->ExtraKindOrNumArgs) {
Mike Stump11289f42009-09-09 15:08:12 +0000240 case DeclarationNameExtra::CXXConstructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000241 return CXXConstructorName;
242
Mike Stump11289f42009-09-09 15:08:12 +0000243 case DeclarationNameExtra::CXXDestructor:
Douglas Gregor77324f32008-11-17 14:58:09 +0000244 return CXXDestructorName;
245
Mike Stump11289f42009-09-09 15:08:12 +0000246 case DeclarationNameExtra::CXXConversionFunction:
Douglas Gregor77324f32008-11-17 14:58:09 +0000247 return CXXConversionFunctionName;
248
Alexis Hunt3d221f22009-11-29 07:34:05 +0000249 case DeclarationNameExtra::CXXLiteralOperator:
250 return CXXLiteralOperatorName;
251
Douglas Gregor889ceb72009-02-03 19:21:40 +0000252 case DeclarationNameExtra::CXXUsingDirective:
253 return CXXUsingDirective;
254
Douglas Gregor77324f32008-11-17 14:58:09 +0000255 default:
Douglas Gregor163c5852008-11-18 14:39:36 +0000256 // Check if we have one of the CXXOperator* enumeration values.
Mike Stump11289f42009-09-09 15:08:12 +0000257 if (getExtra()->ExtraKindOrNumArgs <
Douglas Gregor889ceb72009-02-03 19:21:40 +0000258 DeclarationNameExtra::CXXUsingDirective)
Douglas Gregor163c5852008-11-18 14:39:36 +0000259 return CXXOperatorName;
260
Douglas Gregor77324f32008-11-17 14:58:09 +0000261 return ObjCMultiArgSelector;
262 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000263 }
264
265 // Can't actually get here.
David Blaikie83d382b2011-09-23 05:06:16 +0000266 llvm_unreachable("This should be unreachable!");
Douglas Gregor77324f32008-11-17 14:58:09 +0000267}
268
Douglas Gregorea0a0a92010-01-11 18:40:55 +0000269bool DeclarationName::isDependentName() const {
270 QualType T = getCXXNameType();
271 return !T.isNull() && T->isDependentType();
272}
273
Douglas Gregor92751d42008-11-17 22:58:34 +0000274std::string DeclarationName::getAsString() const {
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000275 std::string Result;
276 llvm::raw_string_ostream OS(Result);
David Blaikied4da8722013-05-14 21:04:00 +0000277 OS << *this;
Benjamin Kramer95c7c422010-04-17 09:56:45 +0000278 return OS.str();
279}
280
Douglas Gregor77324f32008-11-17 14:58:09 +0000281QualType DeclarationName::getCXXNameType() const {
282 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
283 return CXXName->Type;
284 else
285 return QualType();
286}
287
Douglas Gregor163c5852008-11-18 14:39:36 +0000288OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
289 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
Mike Stump11289f42009-09-09 15:08:12 +0000290 unsigned value
Douglas Gregor163c5852008-11-18 14:39:36 +0000291 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
292 return static_cast<OverloadedOperatorKind>(value);
293 } else {
294 return OO_None;
295 }
296}
297
Alexis Hunt3d221f22009-11-29 07:34:05 +0000298IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
299 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
300 return CXXLit->ID;
301 else
Craig Topper36250ad2014-05-12 05:36:57 +0000302 return nullptr;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000303}
304
Douglas Gregor0da53052012-05-03 23:18:44 +0000305void *DeclarationName::getFETokenInfoAsVoidSlow() const {
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000306 switch (getNameKind()) {
307 case Identifier:
Benjamin Kramer1458c1c2012-05-19 16:03:58 +0000308 llvm_unreachable("Handled by getFETokenInfo()");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000309
310 case CXXConstructorName:
311 case CXXDestructorName:
312 case CXXConversionFunctionName:
313 return getAsCXXSpecialName()->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
Douglas Gregor163c5852008-11-18 14:39:36 +0000338 case CXXOperatorName:
339 getAsCXXOperatorIdName()->FETokenInfo = T;
340 break;
341
Alexis Hunt3d221f22009-11-29 07:34:05 +0000342 case CXXLiteralOperatorName:
Richard Smithc1b05652012-03-09 08:37:16 +0000343 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000344 break;
345
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000346 default:
David Blaikie83d382b2011-09-23 05:06:16 +0000347 llvm_unreachable("Declaration name has no FETokenInfo");
Douglas Gregorae2fbad2008-11-17 20:34:05 +0000348 }
349}
350
Douglas Gregor889ceb72009-02-03 19:21:40 +0000351DeclarationName DeclarationName::getUsingDirectiveName() {
352 // Single instance of DeclarationNameExtra for using-directive
Nuno Lopes221c1fd2009-12-10 00:07:02 +0000353 static const DeclarationNameExtra UDirExtra =
Douglas Gregor889ceb72009-02-03 19:21:40 +0000354 { DeclarationNameExtra::CXXUsingDirective };
355
356 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
357 Ptr |= StoredDeclarationNameExtra;
358
359 return DeclarationName(Ptr);
360}
361
Yaron Kerencdae9412016-01-29 19:38:18 +0000362LLVM_DUMP_METHOD void DeclarationName::dump() const {
David Blaikied4da8722013-05-14 21:04:00 +0000363 llvm::errs() << *this << '\n';
Anders Carlsson1b69be22009-11-15 22:30:43 +0000364}
365
Jay Foad39c79802011-01-12 09:06:06 +0000366DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000367 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
Alexis Huntc88db062010-01-13 09:01:02 +0000368 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
Douglas Gregor163c5852008-11-18 14:39:36 +0000369
370 // Initialize the overloaded operator names.
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000371 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
Douglas Gregor163c5852008-11-18 14:39:36 +0000372 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
Mike Stump11289f42009-09-09 15:08:12 +0000373 CXXOperatorNames[Op].ExtraKindOrNumArgs
Douglas Gregor163c5852008-11-18 14:39:36 +0000374 = Op + DeclarationNameExtra::CXXConversionFunction;
Craig Topper36250ad2014-05-12 05:36:57 +0000375 CXXOperatorNames[Op].FETokenInfo = nullptr;
Douglas Gregor163c5852008-11-18 14:39:36 +0000376 }
Douglas Gregor77324f32008-11-17 14:58:09 +0000377}
378
379DeclarationNameTable::~DeclarationNameTable() {
Alexis Huntc88db062010-01-13 09:01:02 +0000380 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
Nuno Lopes127adb42008-12-14 17:27:25 +0000381 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
Alexis Huntc88db062010-01-13 09:01:02 +0000382 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
383 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000384 (CXXLiteralOperatorNames);
Alexis Huntc88db062010-01-13 09:01:02 +0000385
Alexis Huntc88db062010-01-13 09:01:02 +0000386 delete SpecialNames;
387 delete LiteralNames;
Ted Kremenek6aead3a2010-05-10 20:40:08 +0000388}
389
Benjamin Kramerd7d2b1f2012-12-01 16:35:25 +0000390DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
391 return getCXXSpecialName(DeclarationName::CXXConstructorName,
392 Ty.getUnqualifiedType());
393}
394
395DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
396 return getCXXSpecialName(DeclarationName::CXXDestructorName,
397 Ty.getUnqualifiedType());
398}
399
400DeclarationName
401DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
402 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
403}
404
Mike Stump11289f42009-09-09 15:08:12 +0000405DeclarationName
406DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
Douglas Gregor2211d342009-08-05 05:36:45 +0000407 CanQualType Ty) {
Douglas Gregor77324f32008-11-17 14:58:09 +0000408 assert(Kind >= DeclarationName::CXXConstructorName &&
409 Kind <= DeclarationName::CXXConversionFunctionName &&
410 "Kind must be a C++ special name kind");
Mike Stump11289f42009-09-09 15:08:12 +0000411 llvm::FoldingSet<CXXSpecialName> *SpecialNames
Douglas Gregor77324f32008-11-17 14:58:09 +0000412 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
413
414 DeclarationNameExtra::ExtraKind EKind;
415 switch (Kind) {
Mike Stump11289f42009-09-09 15:08:12 +0000416 case DeclarationName::CXXConstructorName:
Douglas Gregor77324f32008-11-17 14:58:09 +0000417 EKind = DeclarationNameExtra::CXXConstructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000418 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000419 break;
420 case DeclarationName::CXXDestructorName:
421 EKind = DeclarationNameExtra::CXXDestructor;
John McCall8ccfcb52009-09-24 19:53:00 +0000422 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
Douglas Gregor77324f32008-11-17 14:58:09 +0000423 break;
424 case DeclarationName::CXXConversionFunctionName:
425 EKind = DeclarationNameExtra::CXXConversionFunction;
426 break;
427 default:
428 return DeclarationName();
429 }
430
431 // Unique selector, to guarantee there is one per name.
432 llvm::FoldingSetNodeID ID;
433 ID.AddInteger(EKind);
434 ID.AddPointer(Ty.getAsOpaquePtr());
435
Craig Topper36250ad2014-05-12 05:36:57 +0000436 void *InsertPos = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000437 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
438 return DeclarationName(Name);
439
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000440 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
Douglas Gregor77324f32008-11-17 14:58:09 +0000441 SpecialName->ExtraKindOrNumArgs = EKind;
442 SpecialName->Type = Ty;
Craig Topper36250ad2014-05-12 05:36:57 +0000443 SpecialName->FETokenInfo = nullptr;
Douglas Gregor77324f32008-11-17 14:58:09 +0000444
445 SpecialNames->InsertNode(SpecialName, InsertPos);
446 return DeclarationName(SpecialName);
447}
448
Mike Stump11289f42009-09-09 15:08:12 +0000449DeclarationName
Douglas Gregor163c5852008-11-18 14:39:36 +0000450DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
451 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
452}
453
Alexis Hunt3d221f22009-11-29 07:34:05 +0000454DeclarationName
455DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
Alexis Huntc88db062010-01-13 09:01:02 +0000456 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
457 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
458 (CXXLiteralOperatorNames);
459
460 llvm::FoldingSetNodeID ID;
461 ID.AddPointer(II);
462
Craig Topper36250ad2014-05-12 05:36:57 +0000463 void *InsertPos = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000464 if (CXXLiteralOperatorIdName *Name =
465 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
466 return DeclarationName (Name);
467
Ted Kremenek7e550ca2010-05-10 20:56:10 +0000468 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
Alexis Hunt3d221f22009-11-29 07:34:05 +0000469 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
470 LiteralName->ID = II;
Craig Topper36250ad2014-05-12 05:36:57 +0000471 LiteralName->FETokenInfo = nullptr;
Alexis Huntc88db062010-01-13 09:01:02 +0000472
473 LiteralNames->InsertNode(LiteralName, InsertPos);
Alexis Hunt3d221f22009-11-29 07:34:05 +0000474 return DeclarationName(LiteralName);
475}
476
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000477DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
478 switch (Name.getNameKind()) {
479 case DeclarationName::Identifier:
480 break;
481 case DeclarationName::CXXConstructorName:
482 case DeclarationName::CXXDestructorName:
483 case DeclarationName::CXXConversionFunctionName:
Craig Topper36250ad2014-05-12 05:36:57 +0000484 NamedType.TInfo = nullptr;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000485 break;
486 case DeclarationName::CXXOperatorName:
487 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
488 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
489 break;
490 case DeclarationName::CXXLiteralOperatorName:
491 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
492 break;
493 case DeclarationName::ObjCZeroArgSelector:
494 case DeclarationName::ObjCOneArgSelector:
495 case DeclarationName::ObjCMultiArgSelector:
496 // FIXME: ?
497 break;
498 case DeclarationName::CXXUsingDirective:
499 break;
500 }
501}
502
Douglas Gregora6e053e2010-12-15 01:34:56 +0000503bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
504 switch (Name.getNameKind()) {
505 case DeclarationName::Identifier:
506 case DeclarationName::ObjCZeroArgSelector:
507 case DeclarationName::ObjCOneArgSelector:
508 case DeclarationName::ObjCMultiArgSelector:
509 case DeclarationName::CXXOperatorName:
510 case DeclarationName::CXXLiteralOperatorName:
511 case DeclarationName::CXXUsingDirective:
512 return false;
513
514 case DeclarationName::CXXConstructorName:
515 case DeclarationName::CXXDestructorName:
516 case DeclarationName::CXXConversionFunctionName:
517 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
518 return TInfo->getType()->containsUnexpandedParameterPack();
519
520 return Name.getCXXNameType()->containsUnexpandedParameterPack();
521 }
Chandler Carruth2b59fbe2010-12-15 07:29:18 +0000522 llvm_unreachable("All name kinds handled.");
Douglas Gregora6e053e2010-12-15 01:34:56 +0000523}
524
Douglas Gregor678d76c2011-07-01 01:22:09 +0000525bool DeclarationNameInfo::isInstantiationDependent() const {
526 switch (Name.getNameKind()) {
527 case DeclarationName::Identifier:
528 case DeclarationName::ObjCZeroArgSelector:
529 case DeclarationName::ObjCOneArgSelector:
530 case DeclarationName::ObjCMultiArgSelector:
531 case DeclarationName::CXXOperatorName:
532 case DeclarationName::CXXLiteralOperatorName:
533 case DeclarationName::CXXUsingDirective:
534 return false;
535
536 case DeclarationName::CXXConstructorName:
537 case DeclarationName::CXXDestructorName:
538 case DeclarationName::CXXConversionFunctionName:
539 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
540 return TInfo->getType()->isInstantiationDependentType();
541
542 return Name.getCXXNameType()->isInstantiationDependentType();
543 }
544 llvm_unreachable("All name kinds handled.");
545}
546
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000547std::string DeclarationNameInfo::getAsString() const {
548 std::string Result;
549 llvm::raw_string_ostream OS(Result);
550 printName(OS);
551 return OS.str();
552}
553
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000554void DeclarationNameInfo::printName(raw_ostream &OS) const {
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000555 switch (Name.getNameKind()) {
556 case DeclarationName::Identifier:
557 case DeclarationName::ObjCZeroArgSelector:
558 case DeclarationName::ObjCOneArgSelector:
559 case DeclarationName::ObjCMultiArgSelector:
560 case DeclarationName::CXXOperatorName:
561 case DeclarationName::CXXLiteralOperatorName:
562 case DeclarationName::CXXUsingDirective:
David Blaikied4da8722013-05-14 21:04:00 +0000563 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000564 return;
565
566 case DeclarationName::CXXConstructorName:
567 case DeclarationName::CXXDestructorName:
568 case DeclarationName::CXXConversionFunctionName:
569 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
570 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
571 OS << '~';
572 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
573 OS << "operator ";
Richard Smithe81daee2014-01-22 00:27:42 +0000574 LangOptions LO;
575 LO.CPlusPlus = true;
Benjamin Kramer00e8a192014-02-25 18:03:55 +0000576 LO.Bool = true;
Richard Smithe81daee2014-01-22 00:27:42 +0000577 OS << TInfo->getType().getAsString(PrintingPolicy(LO));
David Blaikied4da8722013-05-14 21:04:00 +0000578 } else
579 OS << Name;
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000580 return;
581 }
David Blaikie83d382b2011-09-23 05:06:16 +0000582 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000583}
584
585SourceLocation DeclarationNameInfo::getEndLoc() const {
586 switch (Name.getNameKind()) {
587 case DeclarationName::Identifier:
588 return NameLoc;
589
590 case DeclarationName::CXXOperatorName: {
591 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
592 return SourceLocation::getFromRawEncoding(raw);
593 }
594
595 case DeclarationName::CXXLiteralOperatorName: {
596 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
597 return SourceLocation::getFromRawEncoding(raw);
598 }
599
600 case DeclarationName::CXXConstructorName:
601 case DeclarationName::CXXDestructorName:
602 case DeclarationName::CXXConversionFunctionName:
603 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
604 return TInfo->getTypeLoc().getEndLoc();
605 else
606 return NameLoc;
607
608 // DNInfo work in progress: FIXME.
609 case DeclarationName::ObjCZeroArgSelector:
610 case DeclarationName::ObjCOneArgSelector:
611 case DeclarationName::ObjCMultiArgSelector:
612 case DeclarationName::CXXUsingDirective:
613 return NameLoc;
614 }
David Blaikie83d382b2011-09-23 05:06:16 +0000615 llvm_unreachable("Unexpected declaration name kind");
Abramo Bagnarad6d2f182010-08-11 22:01:17 +0000616}