File: | tools/clang/lib/AST/DeclarationName.cpp |
Warning: | line 542, column 35 Access to field 'ExtraKindOrNumArgs' results in a dereference of a null pointer (loaded from variable 'SpecialName') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- DeclarationName.cpp - Declaration names implementation -------------===// | |||
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 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "clang/AST/DeclarationName.h" | |||
16 | #include "clang/AST/ASTContext.h" | |||
17 | #include "clang/AST/Decl.h" | |||
18 | #include "clang/AST/DeclBase.h" | |||
19 | #include "clang/AST/DeclCXX.h" | |||
20 | #include "clang/AST/DeclTemplate.h" | |||
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 | namespace clang { | |||
43 | ||||
44 | /// CXXSpecialName - Records the type associated with one of the | |||
45 | /// "special" kinds of declaration names in C++, e.g., constructors, | |||
46 | /// destructors, and conversion functions. | |||
47 | class CXXSpecialName | |||
48 | : public DeclarationNameExtra, public llvm::FoldingSetNode { | |||
49 | public: | |||
50 | /// Type - The type associated with this declaration name. | |||
51 | QualType Type; | |||
52 | ||||
53 | /// FETokenInfo - Extra information associated with this declaration | |||
54 | /// name that can be used by the front end. | |||
55 | void *FETokenInfo; | |||
56 | ||||
57 | void Profile(llvm::FoldingSetNodeID &ID) { | |||
58 | ID.AddInteger(ExtraKindOrNumArgs); | |||
59 | ID.AddPointer(Type.getAsOpaquePtr()); | |||
60 | } | |||
61 | }; | |||
62 | ||||
63 | /// Contains extra information for the name of a C++ deduction guide. | |||
64 | class CXXDeductionGuideNameExtra : public DeclarationNameExtra, | |||
65 | public llvm::FoldingSetNode { | |||
66 | public: | |||
67 | /// The template named by the deduction guide. | |||
68 | TemplateDecl *Template; | |||
69 | ||||
70 | /// FETokenInfo - Extra information associated with this operator | |||
71 | /// name that can be used by the front end. | |||
72 | void *FETokenInfo; | |||
73 | ||||
74 | void Profile(llvm::FoldingSetNodeID &ID) { | |||
75 | ID.AddPointer(Template); | |||
76 | } | |||
77 | }; | |||
78 | ||||
79 | /// CXXOperatorIdName - Contains extra information for the name of an | |||
80 | /// overloaded operator in C++, such as "operator+. | |||
81 | class CXXOperatorIdName : public DeclarationNameExtra { | |||
82 | public: | |||
83 | /// FETokenInfo - Extra information associated with this operator | |||
84 | /// name that can be used by the front end. | |||
85 | void *FETokenInfo; | |||
86 | }; | |||
87 | ||||
88 | /// CXXLiteralOperatorName - Contains the actual identifier that makes up the | |||
89 | /// name. | |||
90 | /// | |||
91 | /// This identifier is stored here rather than directly in DeclarationName so as | |||
92 | /// to allow Objective-C selectors, which are about a million times more common, | |||
93 | /// to consume minimal memory. | |||
94 | class CXXLiteralOperatorIdName | |||
95 | : public DeclarationNameExtra, public llvm::FoldingSetNode { | |||
96 | public: | |||
97 | IdentifierInfo *ID; | |||
98 | ||||
99 | /// FETokenInfo - Extra information associated with this operator | |||
100 | /// name that can be used by the front end. | |||
101 | void *FETokenInfo; | |||
102 | ||||
103 | void Profile(llvm::FoldingSetNodeID &FSID) { | |||
104 | FSID.AddPointer(ID); | |||
105 | } | |||
106 | }; | |||
107 | ||||
108 | } // namespace clang | |||
109 | ||||
110 | static int compareInt(unsigned A, unsigned B) { | |||
111 | return (A < B ? -1 : (A > B ? 1 : 0)); | |||
112 | } | |||
113 | ||||
114 | int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { | |||
115 | if (LHS.getNameKind() != RHS.getNameKind()) | |||
116 | return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); | |||
117 | ||||
118 | switch (LHS.getNameKind()) { | |||
119 | case DeclarationName::Identifier: { | |||
120 | IdentifierInfo *LII = LHS.getAsIdentifierInfo(); | |||
121 | IdentifierInfo *RII = RHS.getAsIdentifierInfo(); | |||
122 | if (!LII) return RII ? -1 : 0; | |||
123 | if (!RII) return 1; | |||
124 | ||||
125 | return LII->getName().compare(RII->getName()); | |||
126 | } | |||
127 | ||||
128 | case DeclarationName::ObjCZeroArgSelector: | |||
129 | case DeclarationName::ObjCOneArgSelector: | |||
130 | case DeclarationName::ObjCMultiArgSelector: { | |||
131 | Selector LHSSelector = LHS.getObjCSelector(); | |||
132 | Selector RHSSelector = RHS.getObjCSelector(); | |||
133 | // getNumArgs for ZeroArgSelector returns 0, but we still need to compare. | |||
134 | if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector && | |||
135 | RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) { | |||
136 | return LHSSelector.getAsIdentifierInfo()->getName().compare( | |||
137 | RHSSelector.getAsIdentifierInfo()->getName()); | |||
138 | } | |||
139 | unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); | |||
140 | for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { | |||
141 | switch (LHSSelector.getNameForSlot(I).compare( | |||
142 | RHSSelector.getNameForSlot(I))) { | |||
143 | case -1: return -1; | |||
144 | case 1: return 1; | |||
145 | default: break; | |||
146 | } | |||
147 | } | |||
148 | ||||
149 | return compareInt(LN, RN); | |||
150 | } | |||
151 | ||||
152 | case DeclarationName::CXXConstructorName: | |||
153 | case DeclarationName::CXXDestructorName: | |||
154 | case DeclarationName::CXXConversionFunctionName: | |||
155 | if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) | |||
156 | return -1; | |||
157 | if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) | |||
158 | return 1; | |||
159 | return 0; | |||
160 | ||||
161 | case DeclarationName::CXXDeductionGuideName: | |||
162 | // We never want to compare deduction guide names for templates from | |||
163 | // different scopes, so just compare the template-name. | |||
164 | return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(), | |||
165 | RHS.getCXXDeductionGuideTemplate()->getDeclName()); | |||
166 | ||||
167 | case DeclarationName::CXXOperatorName: | |||
168 | return compareInt(LHS.getCXXOverloadedOperator(), | |||
169 | RHS.getCXXOverloadedOperator()); | |||
170 | ||||
171 | case DeclarationName::CXXLiteralOperatorName: | |||
172 | return LHS.getCXXLiteralIdentifier()->getName().compare( | |||
173 | RHS.getCXXLiteralIdentifier()->getName()); | |||
174 | ||||
175 | case DeclarationName::CXXUsingDirective: | |||
176 | return 0; | |||
177 | } | |||
178 | ||||
179 | llvm_unreachable("Invalid DeclarationName Kind!")::llvm::llvm_unreachable_internal("Invalid DeclarationName Kind!" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 179); | |||
180 | } | |||
181 | ||||
182 | static void printCXXConstructorDestructorName(QualType ClassType, | |||
183 | raw_ostream &OS, | |||
184 | PrintingPolicy Policy) { | |||
185 | // We know we're printing C++ here. Ensure we print types properly. | |||
186 | Policy.adjustForCPlusPlus(); | |||
187 | ||||
188 | if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) { | |||
189 | OS << *ClassRec->getDecl(); | |||
190 | return; | |||
191 | } | |||
192 | if (Policy.SuppressTemplateArgsInCXXConstructors) { | |||
193 | if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) { | |||
194 | OS << *InjTy->getDecl(); | |||
195 | return; | |||
196 | } | |||
197 | } | |||
198 | ClassType.print(OS, Policy); | |||
199 | } | |||
200 | ||||
201 | void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { | |||
202 | DeclarationName &N = *this; | |||
203 | switch (N.getNameKind()) { | |||
204 | case DeclarationName::Identifier: | |||
205 | if (const IdentifierInfo *II = N.getAsIdentifierInfo()) | |||
206 | OS << II->getName(); | |||
207 | return; | |||
208 | ||||
209 | case DeclarationName::ObjCZeroArgSelector: | |||
210 | case DeclarationName::ObjCOneArgSelector: | |||
211 | case DeclarationName::ObjCMultiArgSelector: | |||
212 | N.getObjCSelector().print(OS); | |||
213 | return; | |||
214 | ||||
215 | case DeclarationName::CXXConstructorName: | |||
216 | return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); | |||
217 | ||||
218 | case DeclarationName::CXXDestructorName: | |||
219 | OS << '~'; | |||
220 | return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); | |||
221 | ||||
222 | case DeclarationName::CXXDeductionGuideName: | |||
223 | OS << "<deduction guide for "; | |||
224 | getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); | |||
225 | OS << '>'; | |||
226 | return; | |||
227 | ||||
228 | case DeclarationName::CXXOperatorName: { | |||
229 | static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { | |||
230 | nullptr, | |||
231 | #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ | |||
232 | Spelling, | |||
233 | #include "clang/Basic/OperatorKinds.def" | |||
234 | }; | |||
235 | const char *OpName = OperatorNames[N.getCXXOverloadedOperator()]; | |||
236 | assert(OpName && "not an overloaded operator")(static_cast <bool> (OpName && "not an overloaded operator" ) ? void (0) : __assert_fail ("OpName && \"not an overloaded operator\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 236, __extension__ __PRETTY_FUNCTION__)); | |||
237 | ||||
238 | OS << "operator"; | |||
239 | if (OpName[0] >= 'a' && OpName[0] <= 'z') | |||
240 | OS << ' '; | |||
241 | OS << OpName; | |||
242 | return; | |||
243 | } | |||
244 | ||||
245 | case DeclarationName::CXXLiteralOperatorName: | |||
246 | OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); | |||
247 | return; | |||
248 | ||||
249 | case DeclarationName::CXXConversionFunctionName: { | |||
250 | OS << "operator "; | |||
251 | QualType Type = N.getCXXNameType(); | |||
252 | if (const RecordType *Rec = Type->getAs<RecordType>()) { | |||
253 | OS << *Rec->getDecl(); | |||
254 | return; | |||
255 | } | |||
256 | // We know we're printing C++ here, ensure we print 'bool' properly. | |||
257 | PrintingPolicy CXXPolicy = Policy; | |||
258 | CXXPolicy.adjustForCPlusPlus(); | |||
259 | Type.print(OS, CXXPolicy); | |||
260 | return; | |||
261 | } | |||
262 | case DeclarationName::CXXUsingDirective: | |||
263 | OS << "<using-directive>"; | |||
264 | return; | |||
265 | } | |||
266 | ||||
267 | llvm_unreachable("Unexpected declaration name kind")::llvm::llvm_unreachable_internal("Unexpected declaration name kind" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 267); | |||
268 | } | |||
269 | ||||
270 | namespace clang { | |||
271 | ||||
272 | raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { | |||
273 | LangOptions LO; | |||
274 | N.print(OS, PrintingPolicy(LO)); | |||
275 | return OS; | |||
276 | } | |||
277 | ||||
278 | } // namespace clang | |||
279 | ||||
280 | DeclarationName::NameKind DeclarationName::getNameKind() const { | |||
281 | switch (getStoredNameKind()) { | |||
282 | case StoredIdentifier: return Identifier; | |||
283 | case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; | |||
284 | case StoredObjCOneArgSelector: return ObjCOneArgSelector; | |||
285 | ||||
286 | case StoredDeclarationNameExtra: | |||
287 | switch (getExtra()->ExtraKindOrNumArgs) { | |||
288 | case DeclarationNameExtra::CXXConstructor: | |||
289 | return CXXConstructorName; | |||
290 | ||||
291 | case DeclarationNameExtra::CXXDestructor: | |||
292 | return CXXDestructorName; | |||
293 | ||||
294 | case DeclarationNameExtra::CXXDeductionGuide: | |||
295 | return CXXDeductionGuideName; | |||
296 | ||||
297 | case DeclarationNameExtra::CXXConversionFunction: | |||
298 | return CXXConversionFunctionName; | |||
299 | ||||
300 | case DeclarationNameExtra::CXXLiteralOperator: | |||
301 | return CXXLiteralOperatorName; | |||
302 | ||||
303 | case DeclarationNameExtra::CXXUsingDirective: | |||
304 | return CXXUsingDirective; | |||
305 | ||||
306 | default: | |||
307 | // Check if we have one of the CXXOperator* enumeration values. | |||
308 | if (getExtra()->ExtraKindOrNumArgs < | |||
309 | DeclarationNameExtra::CXXUsingDirective) | |||
310 | return CXXOperatorName; | |||
311 | ||||
312 | return ObjCMultiArgSelector; | |||
313 | } | |||
314 | } | |||
315 | ||||
316 | // Can't actually get here. | |||
317 | llvm_unreachable("This should be unreachable!")::llvm::llvm_unreachable_internal("This should be unreachable!" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 317); | |||
318 | } | |||
319 | ||||
320 | bool DeclarationName::isDependentName() const { | |||
321 | QualType T = getCXXNameType(); | |||
322 | if (!T.isNull() && T->isDependentType()) | |||
323 | return true; | |||
324 | ||||
325 | // A class-scope deduction guide in a dependent context has a dependent name. | |||
326 | auto *TD = getCXXDeductionGuideTemplate(); | |||
327 | if (TD && TD->getDeclContext()->isDependentContext()) | |||
328 | return true; | |||
329 | ||||
330 | return false; | |||
331 | } | |||
332 | ||||
333 | std::string DeclarationName::getAsString() const { | |||
334 | std::string Result; | |||
335 | llvm::raw_string_ostream OS(Result); | |||
336 | OS << *this; | |||
337 | return OS.str(); | |||
338 | } | |||
339 | ||||
340 | QualType DeclarationName::getCXXNameType() const { | |||
341 | if (CXXSpecialName *CXXName = getAsCXXSpecialName()) | |||
342 | return CXXName->Type; | |||
343 | else | |||
344 | return QualType(); | |||
345 | } | |||
346 | ||||
347 | TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const { | |||
348 | if (auto *Guide = getAsCXXDeductionGuideNameExtra()) | |||
349 | return Guide->Template; | |||
350 | return nullptr; | |||
351 | } | |||
352 | ||||
353 | OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { | |||
354 | if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { | |||
355 | unsigned value | |||
356 | = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; | |||
357 | return static_cast<OverloadedOperatorKind>(value); | |||
358 | } else { | |||
359 | return OO_None; | |||
360 | } | |||
361 | } | |||
362 | ||||
363 | IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { | |||
364 | if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) | |||
365 | return CXXLit->ID; | |||
366 | else | |||
367 | return nullptr; | |||
368 | } | |||
369 | ||||
370 | void *DeclarationName::getFETokenInfoAsVoidSlow() const { | |||
371 | switch (getNameKind()) { | |||
372 | case Identifier: | |||
373 | llvm_unreachable("Handled by getFETokenInfo()")::llvm::llvm_unreachable_internal("Handled by getFETokenInfo()" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 373); | |||
374 | ||||
375 | case CXXConstructorName: | |||
376 | case CXXDestructorName: | |||
377 | case CXXConversionFunctionName: | |||
378 | return getAsCXXSpecialName()->FETokenInfo; | |||
379 | ||||
380 | case CXXDeductionGuideName: | |||
381 | return getAsCXXDeductionGuideNameExtra()->FETokenInfo; | |||
382 | ||||
383 | case CXXOperatorName: | |||
384 | return getAsCXXOperatorIdName()->FETokenInfo; | |||
385 | ||||
386 | case CXXLiteralOperatorName: | |||
387 | return getAsCXXLiteralOperatorIdName()->FETokenInfo; | |||
388 | ||||
389 | default: | |||
390 | llvm_unreachable("Declaration name has no FETokenInfo")::llvm::llvm_unreachable_internal("Declaration name has no FETokenInfo" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 390); | |||
391 | } | |||
392 | } | |||
393 | ||||
394 | void DeclarationName::setFETokenInfo(void *T) { | |||
395 | switch (getNameKind()) { | |||
396 | case Identifier: | |||
397 | getAsIdentifierInfo()->setFETokenInfo(T); | |||
398 | break; | |||
399 | ||||
400 | case CXXConstructorName: | |||
401 | case CXXDestructorName: | |||
402 | case CXXConversionFunctionName: | |||
403 | getAsCXXSpecialName()->FETokenInfo = T; | |||
404 | break; | |||
405 | ||||
406 | case CXXDeductionGuideName: | |||
407 | getAsCXXDeductionGuideNameExtra()->FETokenInfo = T; | |||
408 | break; | |||
409 | ||||
410 | case CXXOperatorName: | |||
411 | getAsCXXOperatorIdName()->FETokenInfo = T; | |||
412 | break; | |||
413 | ||||
414 | case CXXLiteralOperatorName: | |||
415 | getAsCXXLiteralOperatorIdName()->FETokenInfo = T; | |||
416 | break; | |||
417 | ||||
418 | default: | |||
419 | llvm_unreachable("Declaration name has no FETokenInfo")::llvm::llvm_unreachable_internal("Declaration name has no FETokenInfo" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 419); | |||
420 | } | |||
421 | } | |||
422 | ||||
423 | DeclarationName DeclarationName::getUsingDirectiveName() { | |||
424 | // Single instance of DeclarationNameExtra for using-directive | |||
425 | static const DeclarationNameExtra UDirExtra = | |||
426 | { DeclarationNameExtra::CXXUsingDirective }; | |||
427 | ||||
428 | uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); | |||
429 | Ptr |= StoredDeclarationNameExtra; | |||
430 | ||||
431 | return DeclarationName(Ptr); | |||
432 | } | |||
433 | ||||
434 | LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void DeclarationName::dump() const { | |||
435 | llvm::errs() << *this << '\n'; | |||
436 | } | |||
437 | ||||
438 | DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { | |||
439 | CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; | |||
440 | CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; | |||
441 | CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>; | |||
442 | ||||
443 | // Initialize the overloaded operator names. | |||
444 | CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; | |||
445 | for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { | |||
446 | CXXOperatorNames[Op].ExtraKindOrNumArgs | |||
447 | = Op + DeclarationNameExtra::CXXConversionFunction; | |||
448 | CXXOperatorNames[Op].FETokenInfo = nullptr; | |||
449 | } | |||
450 | } | |||
451 | ||||
452 | DeclarationNameTable::~DeclarationNameTable() { | |||
453 | auto *SpecialNames = | |||
454 | static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl); | |||
455 | auto *LiteralNames = | |||
456 | static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>( | |||
457 | CXXLiteralOperatorNames); | |||
458 | auto *DeductionGuideNames = | |||
459 | static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( | |||
460 | CXXDeductionGuideNames); | |||
461 | ||||
462 | delete SpecialNames; | |||
463 | delete LiteralNames; | |||
464 | delete DeductionGuideNames; | |||
465 | } | |||
466 | ||||
467 | DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { | |||
468 | return getCXXSpecialName(DeclarationName::CXXConstructorName, | |||
469 | Ty.getUnqualifiedType()); | |||
470 | } | |||
471 | ||||
472 | DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { | |||
473 | return getCXXSpecialName(DeclarationName::CXXDestructorName, | |||
474 | Ty.getUnqualifiedType()); | |||
475 | } | |||
476 | ||||
477 | DeclarationName | |||
478 | DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { | |||
479 | Template = cast<TemplateDecl>(Template->getCanonicalDecl()); | |||
480 | ||||
481 | auto *DeductionGuideNames = | |||
482 | static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( | |||
483 | CXXDeductionGuideNames); | |||
484 | ||||
485 | llvm::FoldingSetNodeID ID; | |||
486 | ID.AddPointer(Template); | |||
487 | ||||
488 | void *InsertPos = nullptr; | |||
489 | if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) | |||
490 | return DeclarationName(Name); | |||
491 | ||||
492 | auto *Name = new (Ctx) CXXDeductionGuideNameExtra; | |||
493 | Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; | |||
494 | Name->Template = Template; | |||
495 | Name->FETokenInfo = nullptr; | |||
496 | ||||
497 | DeductionGuideNames->InsertNode(Name, InsertPos); | |||
498 | return DeclarationName(Name); | |||
499 | } | |||
500 | ||||
501 | DeclarationName | |||
502 | DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { | |||
503 | return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); | |||
| ||||
504 | } | |||
505 | ||||
506 | DeclarationName | |||
507 | DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, | |||
508 | CanQualType Ty) { | |||
509 | assert(Kind >= DeclarationName::CXXConstructorName &&(static_cast <bool> (Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && "Kind must be a C++ special name kind") ? void (0 ) : __assert_fail ("Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && \"Kind must be a C++ special name kind\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 511, __extension__ __PRETTY_FUNCTION__)) | |||
510 | Kind <= DeclarationName::CXXConversionFunctionName &&(static_cast <bool> (Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && "Kind must be a C++ special name kind") ? void (0 ) : __assert_fail ("Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && \"Kind must be a C++ special name kind\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 511, __extension__ __PRETTY_FUNCTION__)) | |||
511 | "Kind must be a C++ special name kind")(static_cast <bool> (Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && "Kind must be a C++ special name kind") ? void (0 ) : __assert_fail ("Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && \"Kind must be a C++ special name kind\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 511, __extension__ __PRETTY_FUNCTION__)); | |||
512 | llvm::FoldingSet<CXXSpecialName> *SpecialNames | |||
513 | = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); | |||
514 | ||||
515 | DeclarationNameExtra::ExtraKind EKind; | |||
516 | switch (Kind) { | |||
517 | case DeclarationName::CXXConstructorName: | |||
518 | EKind = DeclarationNameExtra::CXXConstructor; | |||
519 | assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified")(static_cast <bool> (!Ty.hasQualifiers() &&"Constructor type must be unqualified" ) ? void (0) : __assert_fail ("!Ty.hasQualifiers() &&\"Constructor type must be unqualified\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 519, __extension__ __PRETTY_FUNCTION__)); | |||
520 | break; | |||
521 | case DeclarationName::CXXDestructorName: | |||
522 | EKind = DeclarationNameExtra::CXXDestructor; | |||
523 | assert(!Ty.hasQualifiers() && "Destructor type must be unqualified")(static_cast <bool> (!Ty.hasQualifiers() && "Destructor type must be unqualified" ) ? void (0) : __assert_fail ("!Ty.hasQualifiers() && \"Destructor type must be unqualified\"" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 523, __extension__ __PRETTY_FUNCTION__)); | |||
524 | break; | |||
525 | case DeclarationName::CXXConversionFunctionName: | |||
526 | EKind = DeclarationNameExtra::CXXConversionFunction; | |||
527 | break; | |||
528 | default: | |||
529 | return DeclarationName(); | |||
530 | } | |||
531 | ||||
532 | // Unique selector, to guarantee there is one per name. | |||
533 | llvm::FoldingSetNodeID ID; | |||
534 | ID.AddInteger(EKind); | |||
535 | ID.AddPointer(Ty.getAsOpaquePtr()); | |||
536 | ||||
537 | void *InsertPos = nullptr; | |||
538 | if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) | |||
539 | return DeclarationName(Name); | |||
540 | ||||
541 | CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; | |||
542 | SpecialName->ExtraKindOrNumArgs = EKind; | |||
| ||||
543 | SpecialName->Type = Ty; | |||
544 | SpecialName->FETokenInfo = nullptr; | |||
545 | ||||
546 | SpecialNames->InsertNode(SpecialName, InsertPos); | |||
547 | return DeclarationName(SpecialName); | |||
548 | } | |||
549 | ||||
550 | DeclarationName | |||
551 | DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { | |||
552 | return DeclarationName(&CXXOperatorNames[(unsigned)Op]); | |||
553 | } | |||
554 | ||||
555 | DeclarationName | |||
556 | DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { | |||
557 | llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames | |||
558 | = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> | |||
559 | (CXXLiteralOperatorNames); | |||
560 | ||||
561 | llvm::FoldingSetNodeID ID; | |||
562 | ID.AddPointer(II); | |||
563 | ||||
564 | void *InsertPos = nullptr; | |||
565 | if (CXXLiteralOperatorIdName *Name = | |||
566 | LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) | |||
567 | return DeclarationName (Name); | |||
568 | ||||
569 | CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; | |||
570 | LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; | |||
571 | LiteralName->ID = II; | |||
572 | LiteralName->FETokenInfo = nullptr; | |||
573 | ||||
574 | LiteralNames->InsertNode(LiteralName, InsertPos); | |||
575 | return DeclarationName(LiteralName); | |||
576 | } | |||
577 | ||||
578 | DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { | |||
579 | switch (Name.getNameKind()) { | |||
580 | case DeclarationName::Identifier: | |||
581 | case DeclarationName::CXXDeductionGuideName: | |||
582 | break; | |||
583 | case DeclarationName::CXXConstructorName: | |||
584 | case DeclarationName::CXXDestructorName: | |||
585 | case DeclarationName::CXXConversionFunctionName: | |||
586 | NamedType.TInfo = nullptr; | |||
587 | break; | |||
588 | case DeclarationName::CXXOperatorName: | |||
589 | CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); | |||
590 | CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); | |||
591 | break; | |||
592 | case DeclarationName::CXXLiteralOperatorName: | |||
593 | CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); | |||
594 | break; | |||
595 | case DeclarationName::ObjCZeroArgSelector: | |||
596 | case DeclarationName::ObjCOneArgSelector: | |||
597 | case DeclarationName::ObjCMultiArgSelector: | |||
598 | // FIXME: ? | |||
599 | break; | |||
600 | case DeclarationName::CXXUsingDirective: | |||
601 | break; | |||
602 | } | |||
603 | } | |||
604 | ||||
605 | bool DeclarationNameInfo::containsUnexpandedParameterPack() const { | |||
606 | switch (Name.getNameKind()) { | |||
607 | case DeclarationName::Identifier: | |||
608 | case DeclarationName::ObjCZeroArgSelector: | |||
609 | case DeclarationName::ObjCOneArgSelector: | |||
610 | case DeclarationName::ObjCMultiArgSelector: | |||
611 | case DeclarationName::CXXOperatorName: | |||
612 | case DeclarationName::CXXLiteralOperatorName: | |||
613 | case DeclarationName::CXXUsingDirective: | |||
614 | case DeclarationName::CXXDeductionGuideName: | |||
615 | return false; | |||
616 | ||||
617 | case DeclarationName::CXXConstructorName: | |||
618 | case DeclarationName::CXXDestructorName: | |||
619 | case DeclarationName::CXXConversionFunctionName: | |||
620 | if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) | |||
621 | return TInfo->getType()->containsUnexpandedParameterPack(); | |||
622 | ||||
623 | return Name.getCXXNameType()->containsUnexpandedParameterPack(); | |||
624 | } | |||
625 | llvm_unreachable("All name kinds handled.")::llvm::llvm_unreachable_internal("All name kinds handled.", "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 625); | |||
626 | } | |||
627 | ||||
628 | bool DeclarationNameInfo::isInstantiationDependent() const { | |||
629 | switch (Name.getNameKind()) { | |||
630 | case DeclarationName::Identifier: | |||
631 | case DeclarationName::ObjCZeroArgSelector: | |||
632 | case DeclarationName::ObjCOneArgSelector: | |||
633 | case DeclarationName::ObjCMultiArgSelector: | |||
634 | case DeclarationName::CXXOperatorName: | |||
635 | case DeclarationName::CXXLiteralOperatorName: | |||
636 | case DeclarationName::CXXUsingDirective: | |||
637 | case DeclarationName::CXXDeductionGuideName: | |||
638 | return false; | |||
639 | ||||
640 | case DeclarationName::CXXConstructorName: | |||
641 | case DeclarationName::CXXDestructorName: | |||
642 | case DeclarationName::CXXConversionFunctionName: | |||
643 | if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) | |||
644 | return TInfo->getType()->isInstantiationDependentType(); | |||
645 | ||||
646 | return Name.getCXXNameType()->isInstantiationDependentType(); | |||
647 | } | |||
648 | llvm_unreachable("All name kinds handled.")::llvm::llvm_unreachable_internal("All name kinds handled.", "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 648); | |||
649 | } | |||
650 | ||||
651 | std::string DeclarationNameInfo::getAsString() const { | |||
652 | std::string Result; | |||
653 | llvm::raw_string_ostream OS(Result); | |||
654 | printName(OS); | |||
655 | return OS.str(); | |||
656 | } | |||
657 | ||||
658 | void DeclarationNameInfo::printName(raw_ostream &OS) const { | |||
659 | switch (Name.getNameKind()) { | |||
660 | case DeclarationName::Identifier: | |||
661 | case DeclarationName::ObjCZeroArgSelector: | |||
662 | case DeclarationName::ObjCOneArgSelector: | |||
663 | case DeclarationName::ObjCMultiArgSelector: | |||
664 | case DeclarationName::CXXOperatorName: | |||
665 | case DeclarationName::CXXLiteralOperatorName: | |||
666 | case DeclarationName::CXXUsingDirective: | |||
667 | case DeclarationName::CXXDeductionGuideName: | |||
668 | OS << Name; | |||
669 | return; | |||
670 | ||||
671 | case DeclarationName::CXXConstructorName: | |||
672 | case DeclarationName::CXXDestructorName: | |||
673 | case DeclarationName::CXXConversionFunctionName: | |||
674 | if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { | |||
675 | if (Name.getNameKind() == DeclarationName::CXXDestructorName) | |||
676 | OS << '~'; | |||
677 | else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) | |||
678 | OS << "operator "; | |||
679 | LangOptions LO; | |||
680 | LO.CPlusPlus = true; | |||
681 | LO.Bool = true; | |||
682 | PrintingPolicy PP(LO); | |||
683 | PP.SuppressScope = true; | |||
684 | OS << TInfo->getType().getAsString(PP); | |||
685 | } else | |||
686 | OS << Name; | |||
687 | return; | |||
688 | } | |||
689 | llvm_unreachable("Unexpected declaration name kind")::llvm::llvm_unreachable_internal("Unexpected declaration name kind" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 689); | |||
690 | } | |||
691 | ||||
692 | SourceLocation DeclarationNameInfo::getEndLoc() const { | |||
693 | switch (Name.getNameKind()) { | |||
694 | case DeclarationName::Identifier: | |||
695 | case DeclarationName::CXXDeductionGuideName: | |||
696 | return NameLoc; | |||
697 | ||||
698 | case DeclarationName::CXXOperatorName: { | |||
699 | unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; | |||
700 | return SourceLocation::getFromRawEncoding(raw); | |||
701 | } | |||
702 | ||||
703 | case DeclarationName::CXXLiteralOperatorName: { | |||
704 | unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; | |||
705 | return SourceLocation::getFromRawEncoding(raw); | |||
706 | } | |||
707 | ||||
708 | case DeclarationName::CXXConstructorName: | |||
709 | case DeclarationName::CXXDestructorName: | |||
710 | case DeclarationName::CXXConversionFunctionName: | |||
711 | if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) | |||
712 | return TInfo->getTypeLoc().getEndLoc(); | |||
713 | else | |||
714 | return NameLoc; | |||
715 | ||||
716 | // DNInfo work in progress: FIXME. | |||
717 | case DeclarationName::ObjCZeroArgSelector: | |||
718 | case DeclarationName::ObjCOneArgSelector: | |||
719 | case DeclarationName::ObjCMultiArgSelector: | |||
720 | case DeclarationName::CXXUsingDirective: | |||
721 | return NameLoc; | |||
722 | } | |||
723 | llvm_unreachable("Unexpected declaration name kind")::llvm::llvm_unreachable_internal("Unexpected declaration name kind" , "/build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp" , 723); | |||
724 | } |