150
|
1 //===- DeclarationName.cpp - Declaration names implementation -------------===//
|
|
2 //
|
|
3 // 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
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8 //
|
|
9 // This file implements the DeclarationName and DeclarationNameTable
|
|
10 // classes.
|
|
11 //
|
|
12 //===----------------------------------------------------------------------===//
|
|
13
|
|
14 #include "clang/AST/DeclarationName.h"
|
|
15 #include "clang/AST/ASTContext.h"
|
|
16 #include "clang/AST/Decl.h"
|
|
17 #include "clang/AST/DeclBase.h"
|
|
18 #include "clang/AST/DeclCXX.h"
|
|
19 #include "clang/AST/DeclTemplate.h"
|
173
|
20 #include "clang/AST/OpenMPClause.h"
|
150
|
21 #include "clang/AST/PrettyPrinter.h"
|
|
22 #include "clang/AST/Type.h"
|
|
23 #include "clang/AST/TypeLoc.h"
|
|
24 #include "clang/AST/TypeOrdering.h"
|
|
25 #include "clang/Basic/IdentifierTable.h"
|
|
26 #include "clang/Basic/LLVM.h"
|
|
27 #include "clang/Basic/LangOptions.h"
|
|
28 #include "clang/Basic/OperatorKinds.h"
|
|
29 #include "clang/Basic/SourceLocation.h"
|
|
30 #include "llvm/ADT/FoldingSet.h"
|
|
31 #include "llvm/Support/Casting.h"
|
|
32 #include "llvm/Support/Compiler.h"
|
|
33 #include "llvm/Support/ErrorHandling.h"
|
|
34 #include "llvm/Support/raw_ostream.h"
|
|
35 #include <algorithm>
|
|
36 #include <cassert>
|
|
37 #include <cstdint>
|
|
38 #include <string>
|
|
39
|
|
40 using namespace clang;
|
|
41
|
|
42 static int compareInt(unsigned A, unsigned B) {
|
|
43 return (A < B ? -1 : (A > B ? 1 : 0));
|
|
44 }
|
|
45
|
|
46 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
|
|
47 if (LHS.getNameKind() != RHS.getNameKind())
|
|
48 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
|
|
49
|
|
50 switch (LHS.getNameKind()) {
|
|
51 case DeclarationName::Identifier: {
|
|
52 IdentifierInfo *LII = LHS.castAsIdentifierInfo();
|
|
53 IdentifierInfo *RII = RHS.castAsIdentifierInfo();
|
|
54 if (!LII)
|
|
55 return RII ? -1 : 0;
|
|
56 if (!RII)
|
|
57 return 1;
|
|
58
|
|
59 return LII->getName().compare(RII->getName());
|
|
60 }
|
|
61
|
|
62 case DeclarationName::ObjCZeroArgSelector:
|
|
63 case DeclarationName::ObjCOneArgSelector:
|
|
64 case DeclarationName::ObjCMultiArgSelector: {
|
|
65 Selector LHSSelector = LHS.getObjCSelector();
|
|
66 Selector RHSSelector = RHS.getObjCSelector();
|
|
67 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
|
|
68 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
|
|
69 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
|
|
70 return LHSSelector.getAsIdentifierInfo()->getName().compare(
|
|
71 RHSSelector.getAsIdentifierInfo()->getName());
|
|
72 }
|
|
73 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
|
|
74 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
|
|
75 switch (LHSSelector.getNameForSlot(I).compare(
|
|
76 RHSSelector.getNameForSlot(I))) {
|
|
77 case -1:
|
|
78 return -1;
|
|
79 case 1:
|
|
80 return 1;
|
|
81 default:
|
|
82 break;
|
|
83 }
|
|
84 }
|
|
85
|
|
86 return compareInt(LN, RN);
|
|
87 }
|
|
88
|
|
89 case DeclarationName::CXXConstructorName:
|
|
90 case DeclarationName::CXXDestructorName:
|
|
91 case DeclarationName::CXXConversionFunctionName:
|
|
92 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
|
|
93 return -1;
|
|
94 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
|
|
95 return 1;
|
|
96 return 0;
|
|
97
|
|
98 case DeclarationName::CXXDeductionGuideName:
|
|
99 // We never want to compare deduction guide names for templates from
|
|
100 // different scopes, so just compare the template-name.
|
|
101 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
|
|
102 RHS.getCXXDeductionGuideTemplate()->getDeclName());
|
|
103
|
|
104 case DeclarationName::CXXOperatorName:
|
|
105 return compareInt(LHS.getCXXOverloadedOperator(),
|
|
106 RHS.getCXXOverloadedOperator());
|
|
107
|
|
108 case DeclarationName::CXXLiteralOperatorName:
|
|
109 return LHS.getCXXLiteralIdentifier()->getName().compare(
|
|
110 RHS.getCXXLiteralIdentifier()->getName());
|
|
111
|
|
112 case DeclarationName::CXXUsingDirective:
|
|
113 return 0;
|
|
114 }
|
|
115
|
|
116 llvm_unreachable("Invalid DeclarationName Kind!");
|
|
117 }
|
|
118
|
|
119 static void printCXXConstructorDestructorName(QualType ClassType,
|
|
120 raw_ostream &OS,
|
|
121 PrintingPolicy Policy) {
|
|
122 // We know we're printing C++ here. Ensure we print types properly.
|
|
123 Policy.adjustForCPlusPlus();
|
|
124
|
|
125 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
|
|
126 OS << *ClassRec->getDecl();
|
|
127 return;
|
|
128 }
|
|
129 if (Policy.SuppressTemplateArgsInCXXConstructors) {
|
|
130 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
|
|
131 OS << *InjTy->getDecl();
|
|
132 return;
|
|
133 }
|
|
134 }
|
|
135 ClassType.print(OS, Policy);
|
|
136 }
|
|
137
|
|
138 void DeclarationName::print(raw_ostream &OS,
|
|
139 const PrintingPolicy &Policy) const {
|
|
140 switch (getNameKind()) {
|
|
141 case DeclarationName::Identifier:
|
173
|
142 if (const IdentifierInfo *II = getAsIdentifierInfo()) {
|
|
143 StringRef Name = II->getName();
|
|
144 // If this is a mangled OpenMP variant name we strip off the mangling for
|
|
145 // printing. It should not be visible to the user at all.
|
|
146 if (II->isMangledOpenMPVariantName()) {
|
|
147 std::pair<StringRef, StringRef> NameContextPair =
|
|
148 Name.split(getOpenMPVariantManglingSeparatorStr());
|
|
149 OS << NameContextPair.first << "["
|
|
150 << OMPTraitInfo(NameContextPair.second) << "]";
|
|
151 } else {
|
|
152 OS << Name;
|
|
153 }
|
|
154 }
|
150
|
155 return;
|
|
156
|
|
157 case DeclarationName::ObjCZeroArgSelector:
|
|
158 case DeclarationName::ObjCOneArgSelector:
|
|
159 case DeclarationName::ObjCMultiArgSelector:
|
|
160 getObjCSelector().print(OS);
|
|
161 return;
|
|
162
|
|
163 case DeclarationName::CXXConstructorName:
|
|
164 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
|
|
165
|
|
166 case DeclarationName::CXXDestructorName:
|
|
167 OS << '~';
|
|
168 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
|
|
169
|
|
170 case DeclarationName::CXXDeductionGuideName:
|
|
171 OS << "<deduction guide for ";
|
|
172 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
|
|
173 OS << '>';
|
|
174 return;
|
|
175
|
|
176 case DeclarationName::CXXOperatorName: {
|
|
177 const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
|
|
178 assert(OpName && "not an overloaded operator");
|
|
179
|
|
180 OS << "operator";
|
|
181 if (OpName[0] >= 'a' && OpName[0] <= 'z')
|
|
182 OS << ' ';
|
|
183 OS << OpName;
|
|
184 return;
|
|
185 }
|
|
186
|
|
187 case DeclarationName::CXXLiteralOperatorName:
|
|
188 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
|
|
189 return;
|
|
190
|
|
191 case DeclarationName::CXXConversionFunctionName: {
|
|
192 OS << "operator ";
|
|
193 QualType Type = getCXXNameType();
|
|
194 if (const RecordType *Rec = Type->getAs<RecordType>()) {
|
|
195 OS << *Rec->getDecl();
|
|
196 return;
|
|
197 }
|
|
198 // We know we're printing C++ here, ensure we print 'bool' properly.
|
|
199 PrintingPolicy CXXPolicy = Policy;
|
|
200 CXXPolicy.adjustForCPlusPlus();
|
|
201 Type.print(OS, CXXPolicy);
|
|
202 return;
|
|
203 }
|
|
204 case DeclarationName::CXXUsingDirective:
|
|
205 OS << "<using-directive>";
|
|
206 return;
|
|
207 }
|
|
208
|
|
209 llvm_unreachable("Unexpected declaration name kind");
|
|
210 }
|
|
211
|
|
212 namespace clang {
|
|
213
|
|
214 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
|
|
215 LangOptions LO;
|
|
216 N.print(OS, PrintingPolicy(LO));
|
|
217 return OS;
|
|
218 }
|
|
219
|
|
220 } // namespace clang
|
|
221
|
|
222 bool DeclarationName::isDependentName() const {
|
|
223 QualType T = getCXXNameType();
|
|
224 if (!T.isNull() && T->isDependentType())
|
|
225 return true;
|
|
226
|
|
227 // A class-scope deduction guide in a dependent context has a dependent name.
|
|
228 auto *TD = getCXXDeductionGuideTemplate();
|
|
229 if (TD && TD->getDeclContext()->isDependentContext())
|
|
230 return true;
|
|
231
|
|
232 return false;
|
|
233 }
|
|
234
|
|
235 std::string DeclarationName::getAsString() const {
|
|
236 std::string Result;
|
|
237 llvm::raw_string_ostream OS(Result);
|
|
238 OS << *this;
|
|
239 return OS.str();
|
|
240 }
|
|
241
|
|
242 void *DeclarationName::getFETokenInfoSlow() const {
|
|
243 switch (getNameKind()) {
|
|
244 case Identifier:
|
|
245 llvm_unreachable("case Identifier already handled by getFETokenInfo!");
|
|
246 case CXXConstructorName:
|
|
247 case CXXDestructorName:
|
|
248 case CXXConversionFunctionName:
|
|
249 return castAsCXXSpecialNameExtra()->FETokenInfo;
|
|
250 case CXXOperatorName:
|
|
251 return castAsCXXOperatorIdName()->FETokenInfo;
|
|
252 case CXXDeductionGuideName:
|
|
253 return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
|
|
254 case CXXLiteralOperatorName:
|
|
255 return castAsCXXLiteralOperatorIdName()->FETokenInfo;
|
|
256 default:
|
|
257 llvm_unreachable("DeclarationName has no FETokenInfo!");
|
|
258 }
|
|
259 }
|
|
260
|
|
261 void DeclarationName::setFETokenInfoSlow(void *T) {
|
|
262 switch (getNameKind()) {
|
|
263 case Identifier:
|
|
264 llvm_unreachable("case Identifier already handled by setFETokenInfo!");
|
|
265 case CXXConstructorName:
|
|
266 case CXXDestructorName:
|
|
267 case CXXConversionFunctionName:
|
|
268 castAsCXXSpecialNameExtra()->FETokenInfo = T;
|
|
269 break;
|
|
270 case CXXOperatorName:
|
|
271 castAsCXXOperatorIdName()->FETokenInfo = T;
|
|
272 break;
|
|
273 case CXXDeductionGuideName:
|
|
274 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
|
|
275 break;
|
|
276 case CXXLiteralOperatorName:
|
|
277 castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
|
|
278 break;
|
|
279 default:
|
|
280 llvm_unreachable("DeclarationName has no FETokenInfo!");
|
|
281 }
|
|
282 }
|
|
283
|
|
284 LLVM_DUMP_METHOD void DeclarationName::dump() const {
|
|
285 llvm::errs() << *this << '\n';
|
|
286 }
|
|
287
|
|
288 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
|
|
289 // Initialize the overloaded operator names.
|
|
290 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
|
|
291 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
|
|
292 }
|
|
293
|
|
294 DeclarationName
|
|
295 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
|
|
296 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
|
|
297
|
|
298 llvm::FoldingSetNodeID ID;
|
|
299 ID.AddPointer(Template);
|
|
300
|
|
301 void *InsertPos = nullptr;
|
|
302 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
|
|
303 return DeclarationName(Name);
|
|
304
|
|
305 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
|
|
306 CXXDeductionGuideNames.InsertNode(Name, InsertPos);
|
|
307 return DeclarationName(Name);
|
|
308 }
|
|
309
|
|
310 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
|
|
311 // The type of constructors is unqualified.
|
|
312 Ty = Ty.getUnqualifiedType();
|
|
313 // Do we already have this C++ constructor name ?
|
|
314 llvm::FoldingSetNodeID ID;
|
|
315 ID.AddPointer(Ty.getAsOpaquePtr());
|
|
316 void *InsertPos = nullptr;
|
|
317 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
|
|
318 return {Name, DeclarationName::StoredCXXConstructorName};
|
|
319
|
|
320 // We have to create it.
|
|
321 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
|
|
322 CXXConstructorNames.InsertNode(SpecialName, InsertPos);
|
|
323 return {SpecialName, DeclarationName::StoredCXXConstructorName};
|
|
324 }
|
|
325
|
|
326 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
|
|
327 // The type of destructors is unqualified.
|
|
328 Ty = Ty.getUnqualifiedType();
|
|
329 // Do we already have this C++ destructor name ?
|
|
330 llvm::FoldingSetNodeID ID;
|
|
331 ID.AddPointer(Ty.getAsOpaquePtr());
|
|
332 void *InsertPos = nullptr;
|
|
333 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
|
|
334 return {Name, DeclarationName::StoredCXXDestructorName};
|
|
335
|
|
336 // We have to create it.
|
|
337 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
|
|
338 CXXDestructorNames.InsertNode(SpecialName, InsertPos);
|
|
339 return {SpecialName, DeclarationName::StoredCXXDestructorName};
|
|
340 }
|
|
341
|
|
342 DeclarationName
|
|
343 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
|
|
344 // Do we already have this C++ conversion function name ?
|
|
345 llvm::FoldingSetNodeID ID;
|
|
346 ID.AddPointer(Ty.getAsOpaquePtr());
|
|
347 void *InsertPos = nullptr;
|
|
348 if (auto *Name =
|
|
349 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
|
|
350 return {Name, DeclarationName::StoredCXXConversionFunctionName};
|
|
351
|
|
352 // We have to create it.
|
|
353 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
|
|
354 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
|
|
355 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
|
|
356 }
|
|
357
|
|
358 DeclarationName
|
|
359 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
|
|
360 CanQualType Ty) {
|
|
361 switch (Kind) {
|
|
362 case DeclarationName::CXXConstructorName:
|
|
363 return getCXXConstructorName(Ty);
|
|
364 case DeclarationName::CXXDestructorName:
|
|
365 return getCXXDestructorName(Ty);
|
|
366 case DeclarationName::CXXConversionFunctionName:
|
|
367 return getCXXConversionFunctionName(Ty);
|
|
368 default:
|
|
369 llvm_unreachable("Invalid kind in getCXXSpecialName!");
|
|
370 }
|
|
371 }
|
|
372
|
|
373 DeclarationName
|
|
374 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
|
|
375 llvm::FoldingSetNodeID ID;
|
|
376 ID.AddPointer(II);
|
|
377
|
|
378 void *InsertPos = nullptr;
|
|
379 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
|
|
380 return DeclarationName(Name);
|
|
381
|
|
382 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
|
|
383 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
|
|
384 return DeclarationName(LiteralName);
|
|
385 }
|
|
386
|
|
387 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
|
|
388 switch (Name.getNameKind()) {
|
|
389 case DeclarationName::Identifier:
|
|
390 case DeclarationName::CXXDeductionGuideName:
|
|
391 break;
|
|
392 case DeclarationName::CXXConstructorName:
|
|
393 case DeclarationName::CXXDestructorName:
|
|
394 case DeclarationName::CXXConversionFunctionName:
|
|
395 NamedType.TInfo = nullptr;
|
|
396 break;
|
|
397 case DeclarationName::CXXOperatorName:
|
|
398 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
|
|
399 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
|
|
400 break;
|
|
401 case DeclarationName::CXXLiteralOperatorName:
|
|
402 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
|
|
403 break;
|
|
404 case DeclarationName::ObjCZeroArgSelector:
|
|
405 case DeclarationName::ObjCOneArgSelector:
|
|
406 case DeclarationName::ObjCMultiArgSelector:
|
|
407 // FIXME: ?
|
|
408 break;
|
|
409 case DeclarationName::CXXUsingDirective:
|
|
410 break;
|
|
411 }
|
|
412 }
|
|
413
|
|
414 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
|
|
415 switch (Name.getNameKind()) {
|
|
416 case DeclarationName::Identifier:
|
|
417 case DeclarationName::ObjCZeroArgSelector:
|
|
418 case DeclarationName::ObjCOneArgSelector:
|
|
419 case DeclarationName::ObjCMultiArgSelector:
|
|
420 case DeclarationName::CXXOperatorName:
|
|
421 case DeclarationName::CXXLiteralOperatorName:
|
|
422 case DeclarationName::CXXUsingDirective:
|
|
423 case DeclarationName::CXXDeductionGuideName:
|
|
424 return false;
|
|
425
|
|
426 case DeclarationName::CXXConstructorName:
|
|
427 case DeclarationName::CXXDestructorName:
|
|
428 case DeclarationName::CXXConversionFunctionName:
|
|
429 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
|
|
430 return TInfo->getType()->containsUnexpandedParameterPack();
|
|
431
|
|
432 return Name.getCXXNameType()->containsUnexpandedParameterPack();
|
|
433 }
|
|
434 llvm_unreachable("All name kinds handled.");
|
|
435 }
|
|
436
|
|
437 bool DeclarationNameInfo::isInstantiationDependent() const {
|
|
438 switch (Name.getNameKind()) {
|
|
439 case DeclarationName::Identifier:
|
|
440 case DeclarationName::ObjCZeroArgSelector:
|
|
441 case DeclarationName::ObjCOneArgSelector:
|
|
442 case DeclarationName::ObjCMultiArgSelector:
|
|
443 case DeclarationName::CXXOperatorName:
|
|
444 case DeclarationName::CXXLiteralOperatorName:
|
|
445 case DeclarationName::CXXUsingDirective:
|
|
446 case DeclarationName::CXXDeductionGuideName:
|
|
447 return false;
|
|
448
|
|
449 case DeclarationName::CXXConstructorName:
|
|
450 case DeclarationName::CXXDestructorName:
|
|
451 case DeclarationName::CXXConversionFunctionName:
|
|
452 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
|
|
453 return TInfo->getType()->isInstantiationDependentType();
|
|
454
|
|
455 return Name.getCXXNameType()->isInstantiationDependentType();
|
|
456 }
|
|
457 llvm_unreachable("All name kinds handled.");
|
|
458 }
|
|
459
|
|
460 std::string DeclarationNameInfo::getAsString() const {
|
|
461 std::string Result;
|
|
462 llvm::raw_string_ostream OS(Result);
|
|
463 OS << *this;
|
|
464 return OS.str();
|
|
465 }
|
|
466
|
|
467 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
|
|
468 LangOptions LO;
|
|
469 DNInfo.printName(OS, PrintingPolicy(LangOptions()));
|
|
470 return OS;
|
|
471 }
|
|
472
|
|
473 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
|
|
474 switch (Name.getNameKind()) {
|
|
475 case DeclarationName::Identifier:
|
|
476 case DeclarationName::ObjCZeroArgSelector:
|
|
477 case DeclarationName::ObjCOneArgSelector:
|
|
478 case DeclarationName::ObjCMultiArgSelector:
|
|
479 case DeclarationName::CXXOperatorName:
|
|
480 case DeclarationName::CXXLiteralOperatorName:
|
|
481 case DeclarationName::CXXUsingDirective:
|
|
482 case DeclarationName::CXXDeductionGuideName:
|
|
483 Name.print(OS, Policy);
|
|
484 return;
|
|
485
|
|
486 case DeclarationName::CXXConstructorName:
|
|
487 case DeclarationName::CXXDestructorName:
|
|
488 case DeclarationName::CXXConversionFunctionName:
|
|
489 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
|
|
490 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
|
|
491 OS << '~';
|
|
492 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
|
|
493 OS << "operator ";
|
|
494 LangOptions LO;
|
|
495 Policy.adjustForCPlusPlus();
|
|
496 Policy.SuppressScope = true;
|
|
497 OS << TInfo->getType().getAsString(Policy);
|
|
498 } else
|
|
499 Name.print(OS, Policy);
|
|
500 return;
|
|
501 }
|
|
502 llvm_unreachable("Unexpected declaration name kind");
|
|
503 }
|
|
504
|
|
505 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
|
|
506 switch (Name.getNameKind()) {
|
|
507 case DeclarationName::Identifier:
|
|
508 case DeclarationName::CXXDeductionGuideName:
|
|
509 return NameLoc;
|
|
510
|
|
511 case DeclarationName::CXXOperatorName: {
|
|
512 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
|
|
513 return SourceLocation::getFromRawEncoding(raw);
|
|
514 }
|
|
515
|
|
516 case DeclarationName::CXXLiteralOperatorName: {
|
|
517 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
|
|
518 return SourceLocation::getFromRawEncoding(raw);
|
|
519 }
|
|
520
|
|
521 case DeclarationName::CXXConstructorName:
|
|
522 case DeclarationName::CXXDestructorName:
|
|
523 case DeclarationName::CXXConversionFunctionName:
|
|
524 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
|
|
525 return TInfo->getTypeLoc().getEndLoc();
|
|
526 else
|
|
527 return NameLoc;
|
|
528
|
|
529 // DNInfo work in progress: FIXME.
|
|
530 case DeclarationName::ObjCZeroArgSelector:
|
|
531 case DeclarationName::ObjCOneArgSelector:
|
|
532 case DeclarationName::ObjCMultiArgSelector:
|
|
533 case DeclarationName::CXXUsingDirective:
|
|
534 return NameLoc;
|
|
535 }
|
|
536 llvm_unreachable("Unexpected declaration name kind");
|
|
537 }
|