Bug Summary

File:tools/clang/lib/AST/DeclarationName.cpp
Warning:line 493, column 28
Access to field 'ExtraKindOrNumArgs' results in a dereference of a null pointer (loaded from variable 'Name')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DeclarationName.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-7~svn338205/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn338205/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn338205/build-llvm/tools/clang/lib/AST -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-29-043837-17923-1 -x c++ /build/llvm-toolchain-snapshot-7~svn338205/tools/clang/lib/AST/DeclarationName.cpp -faddrsig
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
40using namespace clang;
41
42namespace 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.
47class CXXSpecialName
48 : public DeclarationNameExtra, public llvm::FoldingSetNode {
49public:
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.
64class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
65 public llvm::FoldingSetNode {
66public:
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+.
81class CXXOperatorIdName : public DeclarationNameExtra {
82public:
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.
94class CXXLiteralOperatorIdName
95 : public DeclarationNameExtra, public llvm::FoldingSetNode {
96public:
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
110static int compareInt(unsigned A, unsigned B) {
111 return (A < B ? -1 : (A > B ? 1 : 0));
112}
113
114int 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
182static 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
201void 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
270namespace clang {
271
272raw_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
280DeclarationName::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
320bool 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
333std::string DeclarationName::getAsString() const {
334 std::string Result;
335 llvm::raw_string_ostream OS(Result);
336 OS << *this;
337 return OS.str();
338}
339
340QualType DeclarationName::getCXXNameType() const {
341 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
342 return CXXName->Type;
343 else
344 return QualType();
345}
346
347TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const {
348 if (auto *Guide = getAsCXXDeductionGuideNameExtra())
349 return Guide->Template;
350 return nullptr;
351}
352
353OverloadedOperatorKind 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
363IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
364 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
365 return CXXLit->ID;
366 else
367 return nullptr;
368}
369
370void *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
394void 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
423DeclarationName 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
434LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void DeclarationName::dump() const {
435 llvm::errs() << *this << '\n';
436}
437
438DeclarationNameTable::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
452DeclarationNameTable::~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
467DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
468 return getCXXSpecialName(DeclarationName::CXXConstructorName,
469 Ty.getUnqualifiedType());
470}
471
472DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
473 return getCXXSpecialName(DeclarationName::CXXDestructorName,
474 Ty.getUnqualifiedType());
475}
476
477DeclarationName
478DeclarationNameTable::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))
1
Assuming 'Name' is null
2
Taking false branch
490 return DeclarationName(Name);
491
492 auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
3
'Name' initialized to a null pointer value
493 Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
4
Access to field 'ExtraKindOrNumArgs' results in a dereference of a null pointer (loaded from variable 'Name')
494 Name->Template = Template;
495 Name->FETokenInfo = nullptr;
496
497 DeductionGuideNames->InsertNode(Name, InsertPos);
498 return DeclarationName(Name);
499}
500
501DeclarationName
502DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
503 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
504}
505
506DeclarationName
507DeclarationNameTable::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
550DeclarationName
551DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
552 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
553}
554
555DeclarationName
556DeclarationNameTable::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
578DeclarationNameLoc::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
605bool 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
628bool 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
651std::string DeclarationNameInfo::getAsString() const {
652 std::string Result;
653 llvm::raw_string_ostream OS(Result);
654 printName(OS);
655 return OS.str();
656}
657
658void 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
692SourceLocation 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}