 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
68.7% |
156 / 227 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
74.9% |
170 / 227 |
| |
|
Line Coverage: |
83.3% |
255 / 306 |
| |
 |
|
 |
1 : //===--- ExprCXX.cpp - (C++) Expression AST Node 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 subclesses of Expr class declared in ExprCXX.h
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Basic/IdentifierTable.h"
15 : #include "clang/AST/DeclCXX.h"
16 : #include "clang/AST/DeclTemplate.h"
17 : #include "clang/AST/ExprCXX.h"
18 : using namespace clang;
19 :
20 : //===----------------------------------------------------------------------===//
21 : // Child Iterators for iterating over subexpressions/substatements
22 : //===----------------------------------------------------------------------===//
23 :
24 : // CXXTypeidExpr - has child iterators if the operand is an expression
25 60: Stmt::child_iterator CXXTypeidExpr::child_begin() {
59: branch 1 taken
1: branch 2 taken
26 60: return isTypeOperand() ? child_iterator() : &Operand.Ex;
27 : }
28 60: Stmt::child_iterator CXXTypeidExpr::child_end() {
59: branch 1 taken
1: branch 2 taken
29 60: return isTypeOperand() ? child_iterator() : &Operand.Ex+1;
30 : }
31 :
32 : // CXXBoolLiteralExpr
33 29: Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
34 29: return child_iterator();
35 : }
36 29: Stmt::child_iterator CXXBoolLiteralExpr::child_end() {
37 29: return child_iterator();
38 : }
39 :
40 : // CXXNullPtrLiteralExpr
41 4: Stmt::child_iterator CXXNullPtrLiteralExpr::child_begin() {
42 4: return child_iterator();
43 : }
44 4: Stmt::child_iterator CXXNullPtrLiteralExpr::child_end() {
45 4: return child_iterator();
46 : }
47 :
48 : // CXXThisExpr
49 185: Stmt::child_iterator CXXThisExpr::child_begin() { return child_iterator(); }
50 185: Stmt::child_iterator CXXThisExpr::child_end() { return child_iterator(); }
51 :
52 : // CXXThrowExpr
53 46: Stmt::child_iterator CXXThrowExpr::child_begin() { return &Op; }
54 46: Stmt::child_iterator CXXThrowExpr::child_end() {
55 : // If Op is 0, we are processing throw; which has no children.
45: branch 0 taken
1: branch 1 taken
56 46: return Op ? &Op+1 : &Op;
57 : }
58 :
59 : // CXXDefaultArgExpr
60 84: Stmt::child_iterator CXXDefaultArgExpr::child_begin() {
61 84: return child_iterator();
62 : }
63 84: Stmt::child_iterator CXXDefaultArgExpr::child_end() {
64 84: return child_iterator();
65 : }
66 :
67 : // CXXZeroInitValueExpr
68 46: Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
69 46: return child_iterator();
70 : }
71 46: Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
72 46: return child_iterator();
73 : }
74 :
75 : // CXXNewExpr
76 : CXXNewExpr::CXXNewExpr(bool globalNew, FunctionDecl *operatorNew,
77 : Expr **placementArgs, unsigned numPlaceArgs,
78 : bool parenTypeId, Expr *arraySize,
79 : CXXConstructorDecl *constructor, bool initializer,
80 : Expr **constructorArgs, unsigned numConsArgs,
81 : FunctionDecl *operatorDelete, QualType ty,
82 106: SourceLocation startLoc, SourceLocation endLoc)
83 : : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
84 : GlobalNew(globalNew), ParenTypeId(parenTypeId),
85 : Initializer(initializer), Array(arraySize), NumPlacementArgs(numPlaceArgs),
86 : NumConstructorArgs(numConsArgs), OperatorNew(operatorNew),
87 : OperatorDelete(operatorDelete), Constructor(constructor),
88 106: StartLoc(startLoc), EndLoc(endLoc) {
89 106: unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
90 106: SubExprs = new Stmt*[TotalSize];
91 106: unsigned i = 0;
20: branch 0 taken
86: branch 1 taken
86: branch 2 taken
86: branch 3 taken
92 106: if (Array)
93 20: SubExprs[i++] = arraySize;
36: branch 0 taken
106: branch 1 taken
106: branch 2 taken
106: branch 3 taken
94 142: for (unsigned j = 0; j < NumPlacementArgs; ++j)
95 36: SubExprs[i++] = placementArgs[j];
63: branch 0 taken
106: branch 1 taken
106: branch 2 taken
106: branch 3 taken
96 169: for (unsigned j = 0; j < NumConstructorArgs; ++j)
97 63: SubExprs[i++] = constructorArgs[j];
0: branch 0 not taken
106: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
98 106: assert(i == TotalSize);
99 106: }
100 :
101 19: Stmt::child_iterator CXXNewExpr::child_begin() { return &SubExprs[0]; }
102 19: Stmt::child_iterator CXXNewExpr::child_end() {
103 19: return &SubExprs[0] + Array + getNumPlacementArgs() + getNumConstructorArgs();
104 : }
105 :
106 : // CXXDeleteExpr
107 0: Stmt::child_iterator CXXDeleteExpr::child_begin() { return &Argument; }
108 0: Stmt::child_iterator CXXDeleteExpr::child_end() { return &Argument+1; }
109 :
110 : // CXXPseudoDestructorExpr
111 1: Stmt::child_iterator CXXPseudoDestructorExpr::child_begin() { return &Base; }
112 1: Stmt::child_iterator CXXPseudoDestructorExpr::child_end() {
113 1: return &Base + 1;
114 : }
115 :
116 : // UnresolvedLookupExpr
117 : UnresolvedLookupExpr *
118 : UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
119 : CXXRecordDecl *NamingClass,
120 : NestedNameSpecifier *Qualifier,
121 : SourceRange QualifierRange, DeclarationName Name,
122 : SourceLocation NameLoc, bool ADL,
123 128: const TemplateArgumentListInfo &Args)
124 : {
125 : void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) +
126 128: ExplicitTemplateArgumentList::sizeFor(Args));
127 : UnresolvedLookupExpr *ULE
128 : = new (Mem) UnresolvedLookupExpr(Dependent ? C.DependentTy : C.OverloadTy,
129 : Dependent, NamingClass,
130 : Qualifier, QualifierRange,
131 : Name, NameLoc, ADL,
132 : /*Overload*/ true,
2: branch 0 taken
126: branch 1 taken
128: branch 4 taken
0: branch 5 not taken
133 128: /*ExplicitTemplateArgs*/ true);
134 :
135 128: reinterpret_cast<ExplicitTemplateArgumentList*>(ULE+1)->initializeFrom(Args);
136 :
137 128: return ULE;
138 : }
139 :
140 : bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin,
141 : UnresolvedSetIterator End,
142 1697: const TemplateArgumentListInfo *Args) {
2372: branch 2 taken
1695: branch 3 taken
143 4067: for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
2: branch 3 taken
2370: branch 4 taken
144 2372: if ((*I)->getDeclContext()->isDependentContext())
145 2: return true;
146 :
158: branch 0 taken
1537: branch 1 taken
2: branch 3 taken
156: branch 4 taken
2: branch 5 taken
1693: branch 6 taken
147 1695: if (Args && TemplateSpecializationType::anyDependentTemplateArguments(*Args))
148 2: return true;
149 :
150 1693: return false;
151 : }
152 :
153 181: Stmt::child_iterator UnresolvedLookupExpr::child_begin() {
154 181: return child_iterator();
155 : }
156 181: Stmt::child_iterator UnresolvedLookupExpr::child_end() {
157 181: return child_iterator();
158 : }
159 : // UnaryTypeTraitExpr
160 1: Stmt::child_iterator UnaryTypeTraitExpr::child_begin() {
161 1: return child_iterator();
162 : }
163 1: Stmt::child_iterator UnaryTypeTraitExpr::child_end() {
164 1: return child_iterator();
165 : }
166 :
167 : // DependentScopeDeclRefExpr
168 : DependentScopeDeclRefExpr *
169 : DependentScopeDeclRefExpr::Create(ASTContext &C,
170 : NestedNameSpecifier *Qualifier,
171 : SourceRange QualifierRange,
172 : DeclarationName Name,
173 : SourceLocation NameLoc,
174 39: const TemplateArgumentListInfo *Args) {
175 39: std::size_t size = sizeof(DependentScopeDeclRefExpr);
1: branch 0 taken
38: branch 1 taken
176 39: if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args);
177 39: void *Mem = C.Allocate(size);
178 :
179 : DependentScopeDeclRefExpr *DRE
180 : = new (Mem) DependentScopeDeclRefExpr(C.DependentTy,
181 : Qualifier, QualifierRange,
182 : Name, NameLoc,
39: branch 2 taken
0: branch 3 not taken
183 39: Args != 0);
184 :
1: branch 0 taken
38: branch 1 taken
185 39: if (Args)
186 : reinterpret_cast<ExplicitTemplateArgumentList*>(DRE+1)
187 1: ->initializeFrom(*Args);
188 :
189 39: return DRE;
190 : }
191 :
192 9: StmtIterator DependentScopeDeclRefExpr::child_begin() {
193 9: return child_iterator();
194 : }
195 :
196 9: StmtIterator DependentScopeDeclRefExpr::child_end() {
197 9: return child_iterator();
198 : }
199 :
200 335: bool UnaryTypeTraitExpr::EvaluateTrait(ASTContext& C) const {
0: branch 0 not taken
53: branch 1 taken
5: branch 2 taken
32: branch 3 taken
18: branch 4 taken
22: branch 5 taken
5: branch 6 taken
36: branch 7 taken
44: branch 8 taken
36: branch 9 taken
36: branch 10 taken
48: branch 11 taken
201 335: switch(UTT) {
202 0: default: assert(false && "Unknown type trait or not implemented");
203 53: case UTT_IsPOD: return QueriedType->isPODType();
204 5: case UTT_IsLiteral: return QueriedType->isLiteralType();
205 : case UTT_IsClass: // Fallthrough
206 : case UTT_IsUnion:
12: branch 2 taken
20: branch 3 taken
207 32: if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
208 12: bool Union = Record->getDecl()->isUnion();
8: branch 0 taken
4: branch 1 taken
209 12: return UTT == UTT_IsUnion ? Union : !Union;
210 : }
211 20: return false;
212 18: case UTT_IsEnum: return QueriedType->isEnumeralType();
213 : case UTT_IsPolymorphic:
12: branch 2 taken
10: branch 3 taken
214 22: if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
215 : // Type traits are only parsed in C++, so we've got CXXRecords.
216 12: return cast<CXXRecordDecl>(Record->getDecl())->isPolymorphic();
217 : }
218 10: return false;
219 : case UTT_IsAbstract:
5: branch 2 taken
0: branch 3 not taken
220 5: if (const RecordType *RT = QueriedType->getAs<RecordType>())
221 5: return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
222 0: return false;
223 : case UTT_IsEmpty:
32: branch 2 taken
4: branch 3 taken
224 36: if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
225 : return !Record->getDecl()->isUnion()
30: branch 2 taken
2: branch 3 taken
22: branch 7 taken
8: branch 8 taken
226 32: && cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
227 : }
228 4: return false;
229 : case UTT_HasTrivialConstructor:
230 : // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
231 : // If __is_pod (type) is true then the trait is true, else if type is
232 : // a cv class or union type (or array thereof) with a trivial default
233 : // constructor ([class.ctor]) then the trait is true, else it is false.
17: branch 2 taken
27: branch 3 taken
234 44: if (QueriedType->isPODType())
235 17: return true;
25: branch 0 taken
2: branch 1 taken
236 27: if (const RecordType *RT =
237 27: C.getBaseElementType(QueriedType)->getAs<RecordType>())
238 25: return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialConstructor();
239 2: return false;
240 : case UTT_HasTrivialCopy:
241 : // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
242 : // If __is_pod (type) is true or type is a reference type then
243 : // the trait is true, else if type is a cv class or union type
244 : // with a trivial copy constructor ([class.copy]) then the trait
245 : // is true, else it is false.
20: branch 2 taken
16: branch 3 taken
2: branch 6 taken
18: branch 7 taken
18: branch 8 taken
18: branch 9 taken
246 36: if (QueriedType->isPODType() || QueriedType->isReferenceType())
247 18: return true;
14: branch 2 taken
4: branch 3 taken
248 18: if (const RecordType *RT = QueriedType->getAs<RecordType>())
249 14: return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
250 4: return false;
251 : case UTT_HasTrivialAssign:
252 : // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
253 : // If type is const qualified or is a reference type then the
254 : // trait is false. Otherwise if __is_pod (type) is true then the
255 : // trait is true, else if type is a cv class or union type with
256 : // a trivial copy assignment ([class.copy]) then the trait is
257 : // true, else it is false.
258 : // Note: the const and reference restrictions are interesting,
259 : // given that const and reference members don't prevent a class
260 : // from having a trivial copy assignment operator (but do cause
261 : // errors if the copy assignment operator is actually used, q.v.
262 : // [class.copy]p12).
263 :
6: branch 2 taken
30: branch 3 taken
264 36: if (C.getBaseElementType(QueriedType).isConstQualified())
265 6: return false;
10: branch 2 taken
20: branch 3 taken
266 30: if (QueriedType->isPODType())
267 10: return true;
14: branch 2 taken
6: branch 3 taken
268 20: if (const RecordType *RT = QueriedType->getAs<RecordType>())
269 14: return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
270 6: return false;
271 : case UTT_HasTrivialDestructor:
272 : // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
273 : // If __is_pod (type) is true or type is a reference type
274 : // then the trait is true, else if type is a cv class or union
275 : // type (or array thereof) with a trivial destructor
276 : // ([class.dtor]) then the trait is true, else it is
277 : // false.
31: branch 2 taken
17: branch 3 taken
2: branch 6 taken
29: branch 7 taken
19: branch 8 taken
29: branch 9 taken
278 48: if (QueriedType->isPODType() || QueriedType->isReferenceType())
279 19: return true;
29: branch 0 taken
0: branch 1 not taken
280 29: if (const RecordType *RT =
281 29: C.getBaseElementType(QueriedType)->getAs<RecordType>())
282 29: return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor();
283 0: return false;
284 : }
285 : }
286 :
287 1838: SourceRange CXXConstructExpr::getSourceRange() const {
288 : // FIXME: Should we know where the parentheses are, if there are any?
754: branch 4 taken
1190: branch 5 taken
289 1944: for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
290 : // Ignore CXXDefaultExprs when computing the range, as they don't
291 : // have a range.
648: branch 2 taken
106: branch 3 taken
292 754: if (!isa<CXXDefaultArgExpr>(*I))
293 648: return SourceRange(Loc, (*I)->getLocEnd());
294 : }
295 :
296 1190: return SourceRange(Loc);
297 : }
298 :
299 727: SourceRange CXXOperatorCallExpr::getSourceRange() const {
300 727: OverloadedOperatorKind Kind = getOperator();
722: branch 0 taken
5: branch 1 taken
4: branch 2 taken
718: branch 3 taken
301 727: if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
4: branch 1 taken
5: branch 2 taken
302 9: if (getNumArgs() == 1)
303 : // Prefix operator
304 : return SourceRange(getOperatorLoc(),
305 4: getArg(0)->getSourceRange().getEnd());
306 : else
307 : // Postfix operator
308 : return SourceRange(getArg(0)->getSourceRange().getEnd(),
309 5: getOperatorLoc());
32: branch 0 taken
686: branch 1 taken
310 718: } else if (Kind == OO_Call) {
311 32: return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
12: branch 0 taken
674: branch 1 taken
312 686: } else if (Kind == OO_Subscript) {
313 12: return SourceRange(getArg(0)->getSourceRange().getBegin(), getRParenLoc());
123: branch 1 taken
551: branch 2 taken
314 674: } else if (getNumArgs() == 1) {
315 123: return SourceRange(getOperatorLoc(), getArg(0)->getSourceRange().getEnd());
551: branch 1 taken
0: branch 2 not taken
316 551: } else if (getNumArgs() == 2) {
317 : return SourceRange(getArg(0)->getSourceRange().getBegin(),
318 551: getArg(1)->getSourceRange().getEnd());
319 : } else {
320 0: return SourceRange();
321 : }
322 : }
323 :
324 1: Expr *CXXMemberCallExpr::getImplicitObjectArgument() {
1: branch 3 taken
0: branch 4 not taken
325 1: if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
326 1: return MemExpr->getBase();
327 :
328 : // FIXME: Will eventually need to cope with member pointers.
329 0: return 0;
330 : }
331 :
332 1553: SourceRange CXXMemberCallExpr::getSourceRange() const {
333 1553: SourceLocation LocStart = getCallee()->getLocStart();
0: branch 1 not taken
1553: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
1553: branch 7 taken
334 1553: if (LocStart.isInvalid() && getNumArgs() > 0)
335 0: LocStart = getArg(0)->getLocStart();
336 1553: return SourceRange(LocStart, getRParenLoc());
337 : }
338 :
339 :
340 : //===----------------------------------------------------------------------===//
341 : // Named casts
342 : //===----------------------------------------------------------------------===//
343 :
344 : /// getCastName - Get the name of the C++ cast being used, e.g.,
345 : /// "static_cast", "dynamic_cast", "reinterpret_cast", or
346 : /// "const_cast". The returned pointer must not be freed.
347 0: const char *CXXNamedCastExpr::getCastName() const {
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 5 not taken
348 0: switch (getStmtClass()) {
349 0: case CXXStaticCastExprClass: return "static_cast";
350 0: case CXXDynamicCastExprClass: return "dynamic_cast";
351 0: case CXXReinterpretCastExprClass: return "reinterpret_cast";
352 0: case CXXConstCastExprClass: return "const_cast";
353 0: default: return "<invalid cast>";
354 : }
355 : }
356 :
357 : CXXDefaultArgExpr *
358 : CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc,
359 27: ParmVarDecl *Param, Expr *SubExpr) {
360 27: void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
361 : return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param,
27: branch 1 taken
0: branch 2 not taken
362 27: SubExpr);
363 : }
364 :
365 4: void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {
1: branch 1 taken
3: branch 2 taken
366 4: if (Param.getInt())
367 1: getExpr()->Destroy(C);
368 4: this->~CXXDefaultArgExpr();
369 4: C.Deallocate(this);
370 4: }
371 :
372 : CXXTemporary *CXXTemporary::Create(ASTContext &C,
373 100: const CXXDestructorDecl *Destructor) {
100: branch 1 taken
0: branch 2 not taken
374 100: return new (C) CXXTemporary(Destructor);
375 : }
376 :
377 3: void CXXTemporary::Destroy(ASTContext &Ctx) {
378 3: this->~CXXTemporary();
379 3: Ctx.Deallocate(this);
380 3: }
381 :
382 : CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C,
383 : CXXTemporary *Temp,
384 100: Expr* SubExpr) {
385 : assert(SubExpr->getType()->isRecordType() &&
100: branch 3 taken
0: branch 4 not taken
386 100: "Expression bound to a temporary must have record type!");
387 :
100: branch 1 taken
0: branch 2 not taken
388 200: return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
389 : }
390 :
391 3: void CXXBindTemporaryExpr::DoDestroy(ASTContext &C) {
392 3: Temp->Destroy(C);
393 3: this->~CXXBindTemporaryExpr();
394 3: C.Deallocate(this);
395 3: }
396 :
397 : CXXBindReferenceExpr *CXXBindReferenceExpr::Create(ASTContext &C, Expr *SubExpr,
398 : bool ExtendsLifetime,
399 0: bool RequiresTemporaryCopy) {
400 : return new (C) CXXBindReferenceExpr(SubExpr,
401 : ExtendsLifetime,
0: branch 1 not taken
0: branch 2 not taken
402 0: RequiresTemporaryCopy);
403 : }
404 :
405 0: void CXXBindReferenceExpr::DoDestroy(ASTContext &C) {
406 0: this->~CXXBindReferenceExpr();
407 0: C.Deallocate(this);
408 0: }
409 :
410 : CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
411 : CXXConstructorDecl *Cons,
412 : QualType writtenTy,
413 : SourceLocation tyBeginLoc,
414 : Expr **Args,
415 : unsigned NumArgs,
416 0: SourceLocation rParenLoc)
417 : : CXXConstructExpr(C, CXXTemporaryObjectExprClass, writtenTy, tyBeginLoc,
418 : Cons, false, Args, NumArgs),
419 0: TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {
420 0: }
421 :
422 : CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
423 : SourceLocation Loc,
424 : CXXConstructorDecl *D, bool Elidable,
425 : Expr **Args, unsigned NumArgs,
426 : bool ZeroInitialization,
427 1947: bool BaseInitialization) {
428 : return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
429 : Elidable, Args, NumArgs, ZeroInitialization,
1947: branch 1 taken
0: branch 2 not taken
430 1947: BaseInitialization);
431 : }
432 :
433 : CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
434 : SourceLocation Loc,
435 : CXXConstructorDecl *D, bool elidable,
436 : Expr **args, unsigned numargs,
437 : bool ZeroInitialization,
438 1947: bool BaseInitialization)
439 : : Expr(SC, T,
440 : T->isDependentType(),
441 : (T->isDependentType() ||
442 : CallExpr::hasAnyValueDependentArguments(args, numargs))),
443 : Constructor(D), Loc(Loc), Elidable(elidable),
444 : ZeroInitialization(ZeroInitialization),
1947: branch 2 taken
0: branch 3 not taken
7: branch 5 taken
1940: branch 6 taken
0: branch 12 not taken
0: branch 13 not taken
0: branch 15 not taken
0: branch 16 not taken
445 1947: BaseInitialization(BaseInitialization), Args(0), NumArgs(numargs)
446 : {
738: branch 0 taken
1209: branch 1 taken
1209: branch 2 taken
1209: branch 3 taken
447 1947: if (NumArgs) {
448 738: Args = new (C) Stmt*[NumArgs];
449 :
880: branch 0 taken
738: branch 1 taken
738: branch 2 taken
738: branch 3 taken
450 1618: for (unsigned i = 0; i != NumArgs; ++i) {
0: branch 0 not taken
880: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
451 880: assert(args[i] && "NULL argument in CXXConstructExpr");
452 880: Args[i] = args[i];
453 : }
454 : }
455 1947: }
456 :
457 : CXXConstructExpr::CXXConstructExpr(EmptyShell Empty, ASTContext &C,
458 0: unsigned numargs)
459 0: : Expr(CXXConstructExprClass, Empty), Args(0), NumArgs(numargs)
460 : {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
461 0: if (NumArgs)
462 0: Args = new (C) Stmt*[NumArgs];
463 0: }
464 :
465 58: void CXXConstructExpr::DoDestroy(ASTContext &C) {
466 58: DestroyChildren(C);
23: branch 0 taken
35: branch 1 taken
467 58: if (Args)
468 23: C.Deallocate(Args);
469 58: this->~CXXConstructExpr();
470 58: C.Deallocate(this);
471 58: }
472 :
473 : CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
474 : CXXTemporary **temps,
475 79: unsigned numtemps)
476 : : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
477 : subexpr->isTypeDependent(), subexpr->isValueDependent()),
478 79: SubExpr(subexpr), Temps(0), NumTemps(numtemps) {
79: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
479 79: if (NumTemps > 0) {
480 79: Temps = new CXXTemporary*[NumTemps];
104: branch 0 taken
79: branch 1 taken
79: branch 2 taken
79: branch 3 taken
481 183: for (unsigned i = 0; i < NumTemps; ++i)
482 104: Temps[i] = temps[i];
483 : }
484 79: }
485 :
486 : CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
487 : Expr *SubExpr,
488 : CXXTemporary **Temps,
489 79: unsigned NumTemps) {
79: branch 1 taken
0: branch 2 not taken
490 79: return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps);
491 : }
492 :
493 0: void CXXExprWithTemporaries::DoDestroy(ASTContext &C) {
494 0: DestroyChildren(C);
495 0: this->~CXXExprWithTemporaries();
496 0: C.Deallocate(this);
497 0: }
498 :
499 0: CXXExprWithTemporaries::~CXXExprWithTemporaries() {
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
0: branch 7 not taken
500 0: delete[] Temps;
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
0: branch 10 not taken
501 0: }
502 :
503 : // CXXBindTemporaryExpr
504 26: Stmt::child_iterator CXXBindTemporaryExpr::child_begin() {
505 26: return &SubExpr;
506 : }
507 :
508 27: Stmt::child_iterator CXXBindTemporaryExpr::child_end() {
509 27: return &SubExpr + 1;
510 : }
511 :
512 : // CXXBindReferenceExpr
513 0: Stmt::child_iterator CXXBindReferenceExpr::child_begin() {
514 0: return &SubExpr;
515 : }
516 :
517 0: Stmt::child_iterator CXXBindReferenceExpr::child_end() {
518 0: return &SubExpr + 1;
519 : }
520 :
521 : // CXXConstructExpr
522 309: Stmt::child_iterator CXXConstructExpr::child_begin() {
523 309: return &Args[0];
524 : }
525 309: Stmt::child_iterator CXXConstructExpr::child_end() {
526 309: return &Args[0]+NumArgs;
527 : }
528 :
529 : // CXXExprWithTemporaries
530 15: Stmt::child_iterator CXXExprWithTemporaries::child_begin() {
531 15: return &SubExpr;
532 : }
533 :
534 15: Stmt::child_iterator CXXExprWithTemporaries::child_end() {
535 15: return &SubExpr + 1;
536 : }
537 :
538 : CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(
539 : SourceLocation TyBeginLoc,
540 : QualType T,
541 : SourceLocation LParenLoc,
542 : Expr **Args,
543 : unsigned NumArgs,
544 54: SourceLocation RParenLoc)
545 : : Expr(CXXUnresolvedConstructExprClass, T.getNonReferenceType(),
546 : T->isDependentType(), true),
547 : TyBeginLoc(TyBeginLoc),
548 : Type(T),
549 : LParenLoc(LParenLoc),
550 : RParenLoc(RParenLoc),
551 54: NumArgs(NumArgs) {
552 54: Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1);
553 54: memcpy(StoredArgs, Args, sizeof(Expr *) * NumArgs);
554 54: }
555 :
556 : CXXUnresolvedConstructExpr *
557 : CXXUnresolvedConstructExpr::Create(ASTContext &C,
558 : SourceLocation TyBegin,
559 : QualType T,
560 : SourceLocation LParenLoc,
561 : Expr **Args,
562 : unsigned NumArgs,
563 54: SourceLocation RParenLoc) {
564 : void *Mem = C.Allocate(sizeof(CXXUnresolvedConstructExpr) +
565 54: sizeof(Expr *) * NumArgs);
566 : return new (Mem) CXXUnresolvedConstructExpr(TyBegin, T, LParenLoc,
54: branch 1 taken
0: branch 2 not taken
567 54: Args, NumArgs, RParenLoc);
568 : }
569 :
570 27: Stmt::child_iterator CXXUnresolvedConstructExpr::child_begin() {
571 27: return child_iterator(reinterpret_cast<Stmt **>(this + 1));
572 : }
573 :
574 27: Stmt::child_iterator CXXUnresolvedConstructExpr::child_end() {
575 27: return child_iterator(reinterpret_cast<Stmt **>(this + 1) + NumArgs);
576 : }
577 :
578 : CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C,
579 : Expr *Base, QualType BaseType,
580 : bool IsArrow,
581 : SourceLocation OperatorLoc,
582 : NestedNameSpecifier *Qualifier,
583 : SourceRange QualifierRange,
584 : NamedDecl *FirstQualifierFoundInScope,
585 : DeclarationName Member,
586 : SourceLocation MemberLoc,
587 7: const TemplateArgumentListInfo *TemplateArgs)
588 : : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true),
589 : Base(Base), BaseType(BaseType), IsArrow(IsArrow),
590 : HasExplicitTemplateArgs(TemplateArgs != 0),
591 : OperatorLoc(OperatorLoc),
592 : Qualifier(Qualifier), QualifierRange(QualifierRange),
593 : FirstQualifierFoundInScope(FirstQualifierFoundInScope),
594 7: Member(Member), MemberLoc(MemberLoc) {
7: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
595 7: if (TemplateArgs)
596 7: getExplicitTemplateArgumentList()->initializeFrom(*TemplateArgs);
597 7: }
598 :
599 : CXXDependentScopeMemberExpr *
600 : CXXDependentScopeMemberExpr::Create(ASTContext &C,
601 : Expr *Base, QualType BaseType, bool IsArrow,
602 : SourceLocation OperatorLoc,
603 : NestedNameSpecifier *Qualifier,
604 : SourceRange QualifierRange,
605 : NamedDecl *FirstQualifierFoundInScope,
606 : DeclarationName Member,
607 : SourceLocation MemberLoc,
608 94: const TemplateArgumentListInfo *TemplateArgs) {
87: branch 0 taken
7: branch 1 taken
609 94: if (!TemplateArgs)
610 : return new (C) CXXDependentScopeMemberExpr(C, Base, BaseType,
611 : IsArrow, OperatorLoc,
612 : Qualifier, QualifierRange,
613 : FirstQualifierFoundInScope,
87: branch 1 taken
0: branch 2 not taken
614 87: Member, MemberLoc);
615 :
616 7: std::size_t size = sizeof(CXXDependentScopeMemberExpr);
7: branch 0 taken
0: branch 1 not taken
617 7: if (TemplateArgs)
618 7: size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
619 :
620 7: void *Mem = C.Allocate(size, llvm::alignof<CXXDependentScopeMemberExpr>());
621 : return new (Mem) CXXDependentScopeMemberExpr(C, Base, BaseType,
622 : IsArrow, OperatorLoc,
623 : Qualifier, QualifierRange,
624 : FirstQualifierFoundInScope,
7: branch 1 taken
0: branch 2 not taken
625 7: Member, MemberLoc, TemplateArgs);
626 : }
627 :
628 10: Stmt::child_iterator CXXDependentScopeMemberExpr::child_begin() {
629 10: return child_iterator(&Base);
630 : }
631 :
632 13: Stmt::child_iterator CXXDependentScopeMemberExpr::child_end() {
1: branch 1 taken
12: branch 2 taken
633 13: if (isImplicitAccess())
634 1: return child_iterator(&Base);
635 12: return child_iterator(&Base + 1);
636 : }
637 :
638 : UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent,
639 : bool HasUnresolvedUsing,
640 : Expr *Base, QualType BaseType,
641 : bool IsArrow,
642 : SourceLocation OperatorLoc,
643 : NestedNameSpecifier *Qualifier,
644 : SourceRange QualifierRange,
645 : DeclarationName MemberName,
646 : SourceLocation MemberLoc,
647 180: const TemplateArgumentListInfo *TemplateArgs)
648 : : OverloadExpr(UnresolvedMemberExprClass, T, Dependent,
649 : Qualifier, QualifierRange, MemberName, MemberLoc,
650 : TemplateArgs != 0),
651 : IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
652 180: Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
32: branch 0 taken
148: branch 1 taken
148: branch 2 taken
148: branch 3 taken
653 180: if (TemplateArgs)
654 32: getExplicitTemplateArgs().initializeFrom(*TemplateArgs);
655 180: }
656 :
657 : UnresolvedMemberExpr *
658 : UnresolvedMemberExpr::Create(ASTContext &C, bool Dependent,
659 : bool HasUnresolvedUsing,
660 : Expr *Base, QualType BaseType, bool IsArrow,
661 : SourceLocation OperatorLoc,
662 : NestedNameSpecifier *Qualifier,
663 : SourceRange QualifierRange,
664 : DeclarationName Member,
665 : SourceLocation MemberLoc,
666 180: const TemplateArgumentListInfo *TemplateArgs) {
667 180: std::size_t size = sizeof(UnresolvedMemberExpr);
32: branch 0 taken
148: branch 1 taken
668 180: if (TemplateArgs)
669 32: size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs);
670 :
671 180: void *Mem = C.Allocate(size, llvm::alignof<UnresolvedMemberExpr>());
672 : return new (Mem) UnresolvedMemberExpr(
673 : Dependent ? C.DependentTy : C.OverloadTy,
674 : Dependent, HasUnresolvedUsing, Base, BaseType,
675 : IsArrow, OperatorLoc, Qualifier, QualifierRange,
10: branch 0 taken
170: branch 1 taken
180: branch 4 taken
0: branch 5 not taken
676 180: Member, MemberLoc, TemplateArgs);
677 : }
678 :
679 13: CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
680 : // Unlike for UnresolvedLookupExpr, it is very easy to re-derive this.
681 :
682 : // If there was a nested name specifier, it names the naming class.
683 : // It can't be dependent: after all, we were actually able to do the
684 : // lookup.
685 : const RecordType *RT;
0: branch 1 not taken
13: branch 2 taken
686 13: if (getQualifier()) {
687 0: Type *T = getQualifier()->getAsType();
0: branch 0 not taken
0: branch 1 not taken
688 0: assert(T && "qualifier in member expression does not name type");
689 0: RT = T->getAs<RecordType>();
0: branch 0 not taken
0: branch 1 not taken
690 0: assert(RT && "qualifier in member expression does not name record");
691 :
692 : // Otherwise the naming class must have been the base class.
693 : } else {
694 13: QualType BaseType = getBaseType().getNonReferenceType();
3: branch 1 taken
10: branch 2 taken
695 13: if (isArrow()) {
696 3: const PointerType *PT = BaseType->getAs<PointerType>();
0: branch 0 not taken
3: branch 1 taken
697 3: assert(PT && "base of arrow member access is not pointer");
698 3: BaseType = PT->getPointeeType();
699 : }
700 :
701 13: RT = BaseType->getAs<RecordType>();
0: branch 0 not taken
13: branch 1 taken
702 13: assert(RT && "base of member expression does not name record");
703 : }
704 :
705 13: return cast<CXXRecordDecl>(RT->getDecl());
706 : }
707 :
708 0: Stmt::child_iterator UnresolvedMemberExpr::child_begin() {
709 0: return child_iterator(&Base);
710 : }
711 :
712 0: Stmt::child_iterator UnresolvedMemberExpr::child_end() {
0: branch 1 not taken
0: branch 2 not taken
713 0: if (isImplicitAccess())
714 0: return child_iterator(&Base);
715 0: return child_iterator(&Base + 1);
716 : }
Generated: 2010-02-10 01:31 by zcov