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