 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
62.2% |
92 / 148 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
75.7% |
112 / 148 |
| |
|
Line Coverage: |
86.0% |
178 / 207 |
| |
 |
|
 |
1 : //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the DeclarationName and DeclarationNameTable
11 : // classes.
12 : //
13 : //===----------------------------------------------------------------------===//
14 : #include "clang/AST/DeclarationName.h"
15 : #include "clang/AST/Type.h"
16 : #include "clang/AST/TypeOrdering.h"
17 : #include "clang/AST/Decl.h"
18 : #include "clang/Basic/IdentifierTable.h"
19 : #include "llvm/ADT/DenseMap.h"
20 : #include "llvm/ADT/FoldingSet.h"
21 : #include <cstdio>
22 : using namespace clang;
23 :
24 : namespace clang {
25 : /// CXXSpecialName - Records the type associated with one of the
26 : /// "special" kinds of declaration names in C++, e.g., constructors,
27 : /// destructors, and conversion functions.
28 : class CXXSpecialName
29 8136: : public DeclarationNameExtra, public llvm::FoldingSetNode {
30 : public:
31 : /// Type - The type associated with this declaration name.
32 : QualType Type;
33 :
34 : /// FETokenInfo - Extra information associated with this declaration
35 : /// name that can be used by the front end.
36 : void *FETokenInfo;
37 :
38 17590: void Profile(llvm::FoldingSetNodeID &ID) {
39 17590: ID.AddInteger(ExtraKindOrNumArgs);
40 17590: ID.AddPointer(Type.getAsOpaquePtr());
41 17590: }
42 : };
43 :
44 : /// CXXOperatorIdName - Contains extra information for the name of an
45 : /// overloaded operator in C++, such as "operator+.
46 : class CXXOperatorIdName : public DeclarationNameExtra {
47 : public:
48 : /// FETokenInfo - Extra information associated with this operator
49 : /// name that can be used by the front end.
50 : void *FETokenInfo;
51 : };
52 :
53 : /// CXXLiberalOperatorName - Contains the actual identifier that makes up the
54 : /// name.
55 : ///
56 : /// This identifier is stored here rather than directly in DeclarationName so as
57 : /// to allow Objective-C selectors, which are about a million times more common,
58 : /// to consume minimal memory.
59 : class CXXLiteralOperatorIdName
60 9: : public DeclarationNameExtra, public llvm::FoldingSetNode {
61 : public:
62 : IdentifierInfo *ID;
63 :
64 34: void Profile(llvm::FoldingSetNodeID &FSID) {
65 34: FSID.AddPointer(ID);
66 34: }
67 : };
68 :
69 125: bool operator<(DeclarationName LHS, DeclarationName RHS) {
0: branch 2 not taken
125: branch 3 taken
70 125: if (LHS.getNameKind() != RHS.getNameKind())
71 0: return LHS.getNameKind() < RHS.getNameKind();
72 :
125: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
73 125: switch (LHS.getNameKind()) {
74 : case DeclarationName::Identifier:
75 : return LHS.getAsIdentifierInfo()->getName() <
76 125: RHS.getAsIdentifierInfo()->getName();
77 :
78 : case DeclarationName::ObjCZeroArgSelector:
79 : case DeclarationName::ObjCOneArgSelector:
80 : case DeclarationName::ObjCMultiArgSelector: {
81 0: Selector LHSSelector = LHS.getObjCSelector();
82 0: Selector RHSSelector = RHS.getObjCSelector();
0: branch 0 not taken
0: branch 1 not taken
83 0: for (unsigned I = 0,
84 0: N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs());
85 : I != N; ++I) {
86 0: IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
87 0: IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
88 0: if (!LHSId || !RHSId)
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
89 0: return LHSId && !RHSId;
90 :
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
91 0: switch (LHSId->getName().compare(RHSId->getName())) {
92 0: case -1: return true;
93 0: case 1: return false;
94 : default: break;
95 : }
96 : }
97 :
98 0: return LHSSelector.getNumArgs() < RHSSelector.getNumArgs();
99 : }
100 :
101 : case DeclarationName::CXXConstructorName:
102 : case DeclarationName::CXXDestructorName:
103 : case DeclarationName::CXXConversionFunctionName:
104 0: return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType());
105 :
106 : case DeclarationName::CXXOperatorName:
107 0: return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
108 :
109 : case DeclarationName::CXXLiteralOperatorName:
110 : return LHS.getCXXLiteralIdentifier()->getName() <
111 0: RHS.getCXXLiteralIdentifier()->getName();
112 :
113 : case DeclarationName::CXXUsingDirective:
114 0: return false;
115 : }
116 :
117 0: return false;
118 : }
119 :
120 : } // end namespace clang
121 :
122 15982: DeclarationName::DeclarationName(Selector Sel) {
25: branch 1 taken
15957: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
123 15982: if (!Sel.getAsOpaquePtr()) {
124 25: Ptr = 0;
125 25: return;
126 : }
127 :
10223: branch 1 taken
4733: branch 2 taken
1001: branch 3 taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
128 15957: switch (Sel.getNumArgs()) {
129 : case 0:
130 10223: Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
0: branch 0 not taken
10223: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
131 10223: assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
132 10223: Ptr |= StoredObjCZeroArgSelector;
133 10223: break;
134 :
135 : case 1:
136 4733: Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
0: branch 0 not taken
4733: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
137 4733: assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
138 4733: Ptr |= StoredObjCOneArgSelector;
139 4733: break;
140 :
141 : default:
142 1001: Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
0: branch 0 not taken
1001: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
143 1001: assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
144 1001: Ptr |= StoredDeclarationNameExtra;
145 : break;
146 : }
147 : }
148 :
149 804419: DeclarationName::NameKind DeclarationName::getNameKind() const {
697205: branch 1 taken
13403: branch 2 taken
7660: branch 3 taken
86151: branch 4 taken
0: branch 5 not taken
150 804419: switch (getStoredNameKind()) {
151 697205: case StoredIdentifier: return Identifier;
152 13403: case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
153 7660: case StoredObjCOneArgSelector: return ObjCOneArgSelector;
154 :
155 : case StoredDeclarationNameExtra:
24466: branch 1 taken
10419: branch 2 taken
35669: branch 3 taken
556: branch 4 taken
2: branch 5 taken
15039: branch 6 taken
156 86151: switch (getExtra()->ExtraKindOrNumArgs) {
157 : case DeclarationNameExtra::CXXConstructor:
158 24466: return CXXConstructorName;
159 :
160 : case DeclarationNameExtra::CXXDestructor:
161 10419: return CXXDestructorName;
162 :
163 : case DeclarationNameExtra::CXXConversionFunction:
164 35669: return CXXConversionFunctionName;
165 :
166 : case DeclarationNameExtra::CXXLiteralOperator:
167 556: return CXXLiteralOperatorName;
168 :
169 : case DeclarationNameExtra::CXXUsingDirective:
170 2: return CXXUsingDirective;
171 :
172 : default:
173 : // Check if we have one of the CXXOperator* enumeration values.
13423: branch 1 taken
1616: branch 2 taken
174 15039: if (getExtra()->ExtraKindOrNumArgs <
175 : DeclarationNameExtra::CXXUsingDirective)
176 13423: return CXXOperatorName;
177 :
178 1616: return ObjCMultiArgSelector;
179 : }
180 : break;
181 : }
182 :
183 : // Can't actually get here.
184 0: assert(0 && "This should be unreachable!");
185 : return Identifier;
186 : }
187 :
188 2074: bool DeclarationName::isDependentName() const {
189 2074: QualType T = getCXXNameType();
31: branch 1 taken
2043: branch 2 taken
4: branch 5 taken
27: branch 6 taken
190 2074: return !T.isNull() && T->isDependentType();
191 : }
192 :
193 10326: std::string DeclarationName::getAsString() const {
9601: branch 1 taken
356: branch 2 taken
54: branch 3 taken
112: branch 4 taken
175: branch 5 taken
2: branch 6 taken
24: branch 7 taken
2: branch 8 taken
0: branch 9 not taken
194 10326: switch (getNameKind()) {
195 : case Identifier:
9519: branch 1 taken
82: branch 2 taken
196 9601: if (const IdentifierInfo *II = getAsIdentifierInfo())
197 9519: return II->getName();
198 82: return "";
199 :
200 : case ObjCZeroArgSelector:
201 : case ObjCOneArgSelector:
202 : case ObjCMultiArgSelector:
203 356: return getObjCSelector().getAsString();
204 :
205 : case CXXConstructorName: {
206 54: QualType ClassType = getCXXNameType();
54: branch 2 taken
0: branch 3 not taken
207 54: if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
208 54: return ClassRec->getDecl()->getNameAsString();
209 0: return ClassType.getAsString();
210 : }
211 :
212 : case CXXDestructorName: {
213 112: std::string Result = "~";
214 112: QualType Type = getCXXNameType();
111: branch 2 taken
1: branch 3 taken
215 112: if (const RecordType *Rec = Type->getAs<RecordType>())
216 111: Result += Rec->getDecl()->getNameAsString();
217 : else
218 1: Result += Type.getAsString();
219 112: return Result;
220 : }
221 :
222 : case CXXOperatorName: {
223 : static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
224 : 0,
225 : #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
226 : Spelling,
227 : #include "clang/Basic/OperatorKinds.def"
228 : };
229 175: const char *OpName = OperatorNames[getCXXOverloadedOperator()];
0: branch 0 not taken
175: branch 1 taken
230 175: assert(OpName && "not an overloaded operator");
231 :
232 175: std::string Result = "operator";
37: branch 0 taken
138: branch 1 taken
36: branch 2 taken
1: branch 3 taken
233 175: if (OpName[0] >= 'a' && OpName[0] <= 'z')
234 36: Result += ' ';
235 175: Result += OpName;
236 175: return Result;
237 : }
238 :
239 : case CXXLiteralOperatorName: {
240 2: return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
241 : }
242 :
243 : case CXXConversionFunctionName: {
244 24: std::string Result = "operator ";
245 24: QualType Type = getCXXNameType();
4: branch 2 taken
20: branch 3 taken
246 24: if (const RecordType *Rec = Type->getAs<RecordType>())
247 4: Result += Rec->getDecl()->getNameAsString();
248 : else
249 20: Result += Type.getAsString();
250 24: return Result;
251 : }
252 : case CXXUsingDirective:
253 2: return "<using-directive>";
254 : }
255 :
256 0: assert(false && "Unexpected declaration name kind");
257 : return "";
258 : }
259 :
260 12167: QualType DeclarationName::getCXXNameType() const {
10124: branch 1 taken
2043: branch 2 taken
261 12167: if (CXXSpecialName *CXXName = getAsCXXSpecialName())
262 10124: return CXXName->Type;
263 : else
264 2043: return QualType();
265 : }
266 :
267 9660: OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
2724: branch 1 taken
6936: branch 2 taken
268 9660: if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
269 : unsigned value
270 2724: = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
271 2724: return static_cast<OverloadedOperatorKind>(value);
272 : } else {
273 6936: return OO_None;
274 : }
275 : }
276 :
277 223: IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
223: branch 1 taken
0: branch 2 not taken
278 223: if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
279 223: return CXXLit->ID;
280 : else
281 0: return 0;
282 : }
283 :
284 22199: Selector DeclarationName::getObjCSelector() const {
13123: branch 1 taken
7515: branch 2 taken
1561: branch 3 taken
0: branch 4 not taken
285 22199: switch (getNameKind()) {
286 : case ObjCZeroArgSelector:
287 13123: return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
288 :
289 : case ObjCOneArgSelector:
290 7515: return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
291 :
292 : case ObjCMultiArgSelector:
293 1561: return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
294 :
295 : default:
296 : break;
297 : }
298 :
299 0: return Selector();
300 : }
301 :
302 395656: void *DeclarationName::getFETokenInfoAsVoid() const {
389456: branch 1 taken
4283: branch 2 taken
1732: branch 3 taken
185: branch 4 taken
0: branch 5 not taken
303 395656: switch (getNameKind()) {
304 : case Identifier:
305 389456: return getAsIdentifierInfo()->getFETokenInfo<void>();
306 :
307 : case CXXConstructorName:
308 : case CXXDestructorName:
309 : case CXXConversionFunctionName:
310 4283: return getAsCXXSpecialName()->FETokenInfo;
311 :
312 : case CXXOperatorName:
313 1732: return getAsCXXOperatorIdName()->FETokenInfo;
314 :
315 : case CXXLiteralOperatorName:
316 185: return getCXXLiteralIdentifier()->getFETokenInfo<void>();
317 :
318 : default:
319 0: assert(false && "Declaration name has no FETokenInfo");
320 : }
321 : return 0;
322 : }
323 :
324 112887: void DeclarationName::setFETokenInfo(void *T) {
110642: branch 1 taken
1852: branch 2 taken
378: branch 3 taken
15: branch 4 taken
0: branch 5 not taken
325 112887: switch (getNameKind()) {
326 : case Identifier:
327 110642: getAsIdentifierInfo()->setFETokenInfo(T);
328 110642: break;
329 :
330 : case CXXConstructorName:
331 : case CXXDestructorName:
332 : case CXXConversionFunctionName:
333 1852: getAsCXXSpecialName()->FETokenInfo = T;
334 1852: break;
335 :
336 : case CXXOperatorName:
337 378: getAsCXXOperatorIdName()->FETokenInfo = T;
338 378: break;
339 :
340 : case CXXLiteralOperatorName:
341 15: getCXXLiteralIdentifier()->setFETokenInfo(T);
342 15: break;
343 :
344 : default:
345 0: assert(false && "Declaration name has no FETokenInfo");
346 : }
347 112887: }
348 :
349 68125: DeclarationName DeclarationName::getUsingDirectiveName() {
350 : // Single instance of DeclarationNameExtra for using-directive
351 : static const DeclarationNameExtra UDirExtra =
352 : { DeclarationNameExtra::CXXUsingDirective };
353 :
354 68125: uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
355 68125: Ptr |= StoredDeclarationNameExtra;
356 :
357 68125: return DeclarationName(Ptr);
358 : }
359 :
360 0: void DeclarationName::dump() const {
361 0: fprintf(stderr, "%s\n", getAsString().c_str());
362 0: }
363 :
364 2250: DeclarationNameTable::DeclarationNameTable() {
365 2250: CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
366 2250: CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
367 :
368 : // Initialize the overloaded operator names.
369 2250: CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
99000: branch 0 taken
2250: branch 1 taken
2250: branch 2 taken
2250: branch 3 taken
370 101250: for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
371 : CXXOperatorNames[Op].ExtraKindOrNumArgs
372 99000: = Op + DeclarationNameExtra::CXXConversionFunction;
373 99000: CXXOperatorNames[Op].FETokenInfo = 0;
374 : }
375 2250: }
376 :
377 2146: DeclarationNameTable::~DeclarationNameTable() {
378 : llvm::FoldingSet<CXXSpecialName> *SpecialNames =
379 2146: static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
380 : llvm::FoldingSetIterator<CXXSpecialName>
381 2146: SI = SpecialNames->begin(), SE = SpecialNames->end();
382 :
7978: branch 1 taken
2146: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
383 12270: while (SI != SE) {
384 7978: CXXSpecialName *n = &*SI++;
385 7978: delete n;
386 : }
387 :
388 :
389 : llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
390 : = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
391 2146: (CXXLiteralOperatorNames);
392 : llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
393 2146: LI = LiteralNames->begin(), LE = LiteralNames->end();
394 :
9: branch 1 taken
2146: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
395 4301: while (LI != LE) {
396 9: CXXLiteralOperatorIdName *n = &*LI++;
397 9: delete n;
398 : }
399 :
2146: branch 0 taken
0: branch 1 not taken
2146: branch 3 taken
2146: branch 4 taken
400 2146: delete SpecialNames;
2146: branch 0 taken
0: branch 1 not taken
2146: branch 3 taken
2146: branch 4 taken
401 2146: delete LiteralNames;
2146: branch 0 taken
0: branch 1 not taken
2146: branch 3 taken
2146: branch 4 taken
402 2146: delete [] CXXOperatorNames;
403 2146: }
404 :
405 : DeclarationName
406 : DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
407 20550: CanQualType Ty) {
408 : assert(Kind >= DeclarationName::CXXConstructorName &&
409 : Kind <= DeclarationName::CXXConversionFunctionName &&
20550: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
20550: branch 3 taken
410 20550: "Kind must be a C++ special name kind");
411 : llvm::FoldingSet<CXXSpecialName> *SpecialNames
412 20550: = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
413 :
414 : DeclarationNameExtra::ExtraKind EKind;
13259: branch 0 taken
6456: branch 1 taken
835: branch 2 taken
0: branch 3 not taken
415 20550: switch (Kind) {
416 : case DeclarationName::CXXConstructorName:
417 13259: EKind = DeclarationNameExtra::CXXConstructor;
13259: branch 1 taken
0: branch 2 not taken
418 13259: assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
419 13259: break;
420 : case DeclarationName::CXXDestructorName:
421 6456: EKind = DeclarationNameExtra::CXXDestructor;
6456: branch 1 taken
0: branch 2 not taken
422 6456: assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
423 6456: break;
424 : case DeclarationName::CXXConversionFunctionName:
425 835: EKind = DeclarationNameExtra::CXXConversionFunction;
426 835: break;
427 : default:
428 0: return DeclarationName();
429 : }
430 :
431 : // Unique selector, to guarantee there is one per name.
432 20550: llvm::FoldingSetNodeID ID;
433 20550: ID.AddInteger(EKind);
434 20550: ID.AddPointer(Ty.getAsOpaquePtr());
435 :
436 20550: void *InsertPos = 0;
12414: branch 1 taken
8136: branch 2 taken
437 20550: if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
438 12414: return DeclarationName(Name);
439 :
440 8136: CXXSpecialName *SpecialName = new CXXSpecialName;
441 8136: SpecialName->ExtraKindOrNumArgs = EKind;
442 8136: SpecialName->Type = Ty;
443 8136: SpecialName->FETokenInfo = 0;
444 :
8136: branch 0 taken
0: branch 1 not taken
445 8136: SpecialNames->InsertNode(SpecialName, InsertPos);
446 8136: return DeclarationName(SpecialName);
447 : }
448 :
449 : DeclarationName
450 7828: DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
451 7828: return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
452 : }
453 :
454 : DeclarationName
455 43: DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
456 : llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
457 : = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
458 43: (CXXLiteralOperatorNames);
459 :
460 43: llvm::FoldingSetNodeID ID;
461 43: ID.AddPointer(II);
462 :
463 43: void *InsertPos = 0;
34: branch 0 taken
9: branch 1 taken
464 43: if (CXXLiteralOperatorIdName *Name =
465 43: LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
466 34: return DeclarationName (Name);
467 :
468 9: CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
469 9: LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
470 9: LiteralName->ID = II;
471 :
9: branch 0 taken
0: branch 1 not taken
472 9: LiteralNames->InsertNode(LiteralName, InsertPos);
473 9: return DeclarationName(LiteralName);
474 : }
475 :
476 : unsigned
477 : llvm::DenseMapInfo<clang::DeclarationName>::
478 208458: getHashValue(clang::DeclarationName N) {
479 208458: return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
480 : }
481 :
Generated: 2010-02-10 01:31 by zcov