 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
65.9% |
91 / 138 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
87.0% |
120 / 138 |
| |
|
Line Coverage: |
83.0% |
273 / 329 |
| |
 |
|
 |
1 : //===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
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 contains code to emit Aggregate Expr nodes as LLVM code.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "CodeGenFunction.h"
15 : #include "CodeGenModule.h"
16 : #include "CGObjCRuntime.h"
17 : #include "clang/AST/ASTContext.h"
18 : #include "clang/AST/DeclCXX.h"
19 : #include "clang/AST/StmtVisitor.h"
20 : #include "llvm/Constants.h"
21 : #include "llvm/Function.h"
22 : #include "llvm/GlobalVariable.h"
23 : #include "llvm/Intrinsics.h"
24 : using namespace clang;
25 : using namespace CodeGen;
26 :
27 : //===----------------------------------------------------------------------===//
28 : // Aggregate Expression Emitter
29 : //===----------------------------------------------------------------------===//
30 :
31 : namespace {
32 : class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
33 : CodeGenFunction &CGF;
34 : CGBuilderTy &Builder;
35 : llvm::Value *DestPtr;
36 : bool VolatileDest;
37 : bool IgnoreResult;
38 : bool IsInitializer;
39 : bool RequiresGCollection;
40 : public:
41 : AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
42 1110: bool ignore, bool isinit, bool requiresGCollection)
43 : : CGF(cgf), Builder(CGF.Builder),
44 : DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
45 1110: IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
46 1110: }
47 :
48 : //===--------------------------------------------------------------------===//
49 : // Utilities
50 : //===--------------------------------------------------------------------===//
51 :
52 : /// EmitAggLoadOfLValue - Given an expression with aggregate type that
53 : /// represents a value lvalue, this method emits the address of the lvalue,
54 : /// then loads the result into DestPtr.
55 : void EmitAggLoadOfLValue(const Expr *E);
56 :
57 : /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
58 : void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
59 : void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
60 :
61 : //===--------------------------------------------------------------------===//
62 : // Visitor Methods
63 : //===--------------------------------------------------------------------===//
64 :
65 0: void VisitStmt(Stmt *S) {
66 0: CGF.ErrorUnsupported(S, "aggregate expression");
67 0: }
68 10: void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
69 0: void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
70 :
71 : // l-values.
72 81: void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
73 8: void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
74 6: void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
75 5: void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
76 17: void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
77 17: EmitAggLoadOfLValue(E);
78 17: }
79 2: void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
80 2: EmitAggLoadOfLValue(E);
81 2: }
82 1: void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
83 1: EmitAggLoadOfLValue(E);
84 1: }
85 1: void VisitPredefinedExpr(const PredefinedExpr *E) {
86 1: EmitAggLoadOfLValue(E);
87 1: }
88 :
89 : // Operators.
90 : void VisitCastExpr(CastExpr *E);
91 : void VisitCallExpr(const CallExpr *E);
92 : void VisitStmtExpr(const StmtExpr *E);
93 : void VisitBinaryOperator(const BinaryOperator *BO);
94 : void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
95 : void VisitBinAssign(const BinaryOperator *E);
96 : void VisitBinComma(const BinaryOperator *E);
97 : void VisitUnaryAddrOf(const UnaryOperator *E);
98 :
99 : void VisitObjCMessageExpr(ObjCMessageExpr *E);
100 2: void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
101 2: EmitAggLoadOfLValue(E);
102 2: }
103 : void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
104 : void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E);
105 :
106 : void VisitConditionalOperator(const ConditionalOperator *CO);
107 : void VisitChooseExpr(const ChooseExpr *CE);
108 : void VisitInitListExpr(InitListExpr *E);
109 : void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
110 7: void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
111 7: Visit(DAE->getExpr());
112 7: }
113 : void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
114 : void VisitCXXConstructExpr(const CXXConstructExpr *E);
115 : void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
116 : void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
117 14: void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
118 :
119 : void VisitVAArgExpr(VAArgExpr *E);
120 :
121 : void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
122 : void EmitNullInitializationToLValue(LValue Address, QualType T);
123 : // case Expr::ChooseExprClass:
124 0: void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
125 : };
126 : } // end anonymous namespace.
127 :
128 : //===----------------------------------------------------------------------===//
129 : // Utilities
130 : //===----------------------------------------------------------------------===//
131 :
132 : /// EmitAggLoadOfLValue - Given an expression with aggregate type that
133 : /// represents a value lvalue, this method emits the address of the lvalue,
134 : /// then loads the result into DestPtr.
135 156: void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
136 156: LValue LV = CGF.EmitLValue(E);
137 156: EmitFinalDestCopy(E, LV);
138 156: }
139 :
140 : /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
141 203: void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
203: branch 1 taken
0: branch 2 not taken
142 203: assert(Src.isAggregate() && "value must be aggregate value!");
143 :
144 : // If the result is ignored, don't copy from the value.
78: branch 0 taken
125: branch 1 taken
145 203: if (DestPtr == 0) {
9: branch 1 taken
69: branch 2 taken
8: branch 3 taken
1: branch 4 taken
5: branch 5 taken
3: branch 6 taken
74: branch 7 taken
4: branch 8 taken
146 78: if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
147 74: return;
148 : // If the source is volatile, we must read from it; to do that, we need
149 : // some place to put it.
150 4: DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
151 : }
152 :
5: branch 0 taken
124: branch 1 taken
153 129: if (RequiresGCollection) {
154 : CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
155 : DestPtr, Src.getAggregateAddr(),
156 5: E->getType());
157 5: return;
158 : }
159 : // If the result of the assignment is used, copy the LHS there also.
160 : // FIXME: Pass VolatileDest as well. I think we also need to merge volatile
161 : // from the source as well, as we can't eliminate it if either operand
162 : // is volatile, unless copy has volatile for both source and destination..
163 : CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(),
164 124: VolatileDest|Src.isVolatileQualified());
165 : }
166 :
167 : /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
168 193: void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
193: branch 1 taken
0: branch 2 not taken
169 193: assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
170 :
171 : EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
172 : Src.isVolatileQualified()),
173 193: Ignore);
174 193: }
175 :
176 : //===----------------------------------------------------------------------===//
177 : // Visitor Methods
178 : //===----------------------------------------------------------------------===//
179 :
180 153: void AggExprEmitter::VisitCastExpr(CastExpr *E) {
0: branch 1 not taken
3: branch 2 taken
142: branch 3 taken
4: branch 4 taken
0: branch 5 not taken
4: branch 6 taken
181 153: switch (E->getCastKind()) {
182 0: default: assert(0 && "Unhandled cast kind!");
183 :
184 : case CastExpr::CK_ToUnion: {
185 : // GCC union extension
186 : QualType PtrTy =
187 3: CGF.getContext().getPointerType(E->getSubExpr()->getType());
188 : llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
189 3: CGF.ConvertType(PtrTy));
190 : EmitInitializationToLValue(E->getSubExpr(),
191 : LValue::MakeAddr(CastPtr, Qualifiers()),
192 3: E->getType());
193 3: break;
194 : }
195 :
196 : // FIXME: Remove the CK_Unknown check here.
197 : case CastExpr::CK_Unknown:
198 : case CastExpr::CK_NoOp:
199 : case CastExpr::CK_UserDefinedConversion:
200 : case CastExpr::CK_ConstructorConversion:
201 : assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
202 : E->getType()) &&
142: branch 5 taken
0: branch 6 not taken
203 142: "Implicit cast types must be compatible");
204 142: Visit(E->getSubExpr());
205 142: break;
206 :
207 : case CastExpr::CK_NullToMemberPointer: {
208 : const llvm::Type *PtrDiffTy =
209 4: CGF.ConvertType(CGF.getContext().getPointerDiffType());
210 :
211 4: llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy);
212 4: llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr");
213 4: Builder.CreateStore(NullValue, Ptr, VolatileDest);
214 :
215 4: llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj");
216 4: Builder.CreateStore(NullValue, Adj, VolatileDest);
217 :
218 4: break;
219 : }
220 :
221 : case CastExpr::CK_BitCast: {
222 : // This must be a member function pointer cast.
223 0: Visit(E->getSubExpr());
224 0: break;
225 : }
226 :
227 : case CastExpr::CK_DerivedToBaseMemberPointer:
228 : case CastExpr::CK_BaseToDerivedMemberPointer: {
229 4: QualType SrcType = E->getSubExpr()->getType();
230 :
231 4: llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
232 4: CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
233 :
234 4: llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
235 4: SrcPtr = Builder.CreateLoad(SrcPtr);
236 :
237 4: llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
238 4: SrcAdj = Builder.CreateLoad(SrcAdj);
239 :
240 4: llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
241 4: Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
242 :
243 4: llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
244 :
245 : // Now See if we need to update the adjustment.
246 : const CXXRecordDecl *BaseDecl =
247 : cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()->
248 4: getClass()->getAs<RecordType>()->getDecl());
249 : const CXXRecordDecl *DerivedDecl =
250 : cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
251 4: getClass()->getAs<RecordType>()->getDecl());
1: branch 1 taken
3: branch 2 taken
252 4: if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
253 1: std::swap(DerivedDecl, BaseDecl);
254 :
2: branch 0 taken
2: branch 1 taken
255 4: if (llvm::Constant *Adj =
256 4: CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, BaseDecl)) {
1: branch 1 taken
1: branch 2 taken
257 2: if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
258 1: SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
259 : else
260 1: SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
261 : }
262 :
263 4: Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
264 : break;
265 : }
266 : }
267 153: }
268 :
269 57: void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
19: branch 3 taken
38: branch 4 taken
270 57: if (E->getCallReturnType()->isReferenceType()) {
271 19: EmitAggLoadOfLValue(E);
272 19: return;
273 : }
274 :
275 : // If the struct doesn't require GC, we can just pass the destination
276 : // directly to EmitCall.
36: branch 0 taken
2: branch 1 taken
277 38: if (!RequiresGCollection) {
278 36: CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
279 36: return;
280 : }
281 :
282 2: RValue RV = CGF.EmitCallExpr(E);
283 2: EmitFinalDestCopy(E, RV);
284 : }
285 :
286 4: void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
287 4: RValue RV = CGF.EmitObjCMessageExpr(E);
288 4: EmitFinalDestCopy(E, RV);
289 4: }
290 :
291 4: void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
292 4: RValue RV = CGF.EmitObjCPropertyGet(E);
293 4: EmitFinalDestCopy(E, RV);
294 4: }
295 :
296 : void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
297 0: ObjCImplicitSetterGetterRefExpr *E) {
298 0: RValue RV = CGF.EmitObjCPropertyGet(E);
299 0: EmitFinalDestCopy(E, RV);
300 0: }
301 :
302 5: void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
303 5: CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
304 : CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
305 5: /*IgnoreResult=*/false, IsInitializer);
306 5: }
307 :
308 12: void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
309 : // We have a member function pointer.
310 12: const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
311 : (void) MPT;
312 : assert(MPT->getPointeeType()->isFunctionProtoType() &&
12: branch 3 taken
0: branch 4 not taken
313 12: "Unexpected member pointer type!");
314 :
315 12: const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
316 : const CXXMethodDecl *MD =
317 12: cast<CXXMethodDecl>(DRE->getDecl())->getCanonicalDecl();
318 :
319 : const llvm::Type *PtrDiffTy =
320 12: CGF.ConvertType(CGF.getContext().getPointerDiffType());
321 :
322 12: llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
323 : llvm::Value *FuncPtr;
324 :
5: branch 1 taken
7: branch 2 taken
325 12: if (MD->isVirtual()) {
326 : int64_t Index =
327 5: CGF.CGM.getVtableInfo().getMethodVtableIndex(MD);
328 :
329 : // Itanium C++ ABI 2.3:
330 : // For a non-virtual function, this field is a simple function pointer.
331 : // For a virtual function, it is 1 plus the virtual table offset
332 : // (in bytes) of the function, represented as a ptrdiff_t.
333 5: FuncPtr = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1);
334 : } else {
335 7: const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
336 : const llvm::Type *Ty =
337 : CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD),
338 7: FPT->isVariadic());
339 7: llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty);
340 7: FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy);
341 : }
342 12: Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
343 :
344 12: llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
345 :
346 : // The adjustment will always be 0.
347 : Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr,
348 12: VolatileDest);
349 12: }
350 :
351 1: void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
352 1: CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
353 1: }
354 :
355 0: void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
356 0: if (E->getOpcode() == BinaryOperator::PtrMemD ||
357 : E->getOpcode() == BinaryOperator::PtrMemI)
358 0: VisitPointerToDataMemberBinaryOperator(E);
359 : else
360 0: CGF.ErrorUnsupported(E, "aggregate binary expression");
361 0: }
362 :
363 : void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
364 0: const BinaryOperator *E) {
365 0: LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
366 0: EmitFinalDestCopy(E, LV);
367 0: }
368 :
369 42: void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
370 : // For an assignment to work, the value on the right has
371 : // to be compatible with the value on the left.
372 : assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
373 : E->getRHS()->getType())
42: branch 6 taken
0: branch 7 not taken
374 42: && "Invalid assignment");
375 42: LValue LHS = CGF.EmitLValue(E->getLHS());
376 :
377 : // We have to special case property setters, otherwise we must have
378 : // a simple lvalue (no aggregates inside vectors, bitfields).
7: branch 1 taken
35: branch 2 taken
379 42: if (LHS.isPropertyRef()) {
380 7: llvm::Value *AggLoc = DestPtr;
6: branch 0 taken
1: branch 1 taken
381 7: if (!AggLoc)
382 6: AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
383 7: CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
384 : CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
385 7: RValue::getAggregate(AggLoc, VolatileDest));
0: branch 1 not taken
35: branch 2 taken
386 35: } else if (LHS.isKVCRef()) {
387 0: llvm::Value *AggLoc = DestPtr;
0: branch 0 not taken
0: branch 1 not taken
388 0: if (!AggLoc)
389 0: AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
390 0: CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
391 : CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
392 0: RValue::getAggregate(AggLoc, VolatileDest));
393 : } else {
394 35: bool RequiresGCollection = false;
35: branch 2 taken
0: branch 3 not taken
395 35: if (CGF.getContext().getLangOptions().NeXTRuntime) {
396 35: QualType LHSTy = E->getLHS()->getType();
31: branch 2 taken
4: branch 3 taken
397 35: if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
398 31: RequiresGCollection = FDTTy->getDecl()->hasObjectMember();
399 : }
400 : // Codegen the RHS so that it stores directly into the LHS.
401 : CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
402 35: false, false, RequiresGCollection);
403 35: EmitFinalDestCopy(E, LHS, true);
404 : }
405 42: }
406 :
407 6: void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
0: branch 1 not taken
6: branch 2 taken
408 6: if (!E->getLHS()) {
409 0: CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
410 0: return;
411 : }
412 :
413 6: llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
414 6: llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
415 6: llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
416 :
417 6: CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
418 :
419 6: CGF.BeginConditionalBranch();
420 6: CGF.EmitBlock(LHSBlock);
421 :
422 : // Handle the GNU extension for missing LHS.
6: branch 1 taken
0: branch 2 not taken
423 6: assert(E->getLHS() && "Must have LHS for aggregate value");
424 :
425 6: Visit(E->getLHS());
426 6: CGF.EndConditionalBranch();
427 6: CGF.EmitBranch(ContBlock);
428 :
429 6: CGF.BeginConditionalBranch();
430 6: CGF.EmitBlock(RHSBlock);
431 :
432 6: Visit(E->getRHS());
433 6: CGF.EndConditionalBranch();
434 6: CGF.EmitBranch(ContBlock);
435 :
436 6: CGF.EmitBlock(ContBlock);
437 : }
438 :
439 0: void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
440 0: Visit(CE->getChosenSubExpr(CGF.getContext()));
441 0: }
442 :
443 2: void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
444 2: llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
445 2: llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
446 :
0: branch 0 not taken
2: branch 1 taken
447 2: if (!ArgPtr) {
448 0: CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
449 0: return;
450 : }
451 :
452 2: EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
453 : }
454 :
455 51: void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
456 51: llvm::Value *Val = DestPtr;
457 :
6: branch 0 taken
45: branch 1 taken
458 51: if (!Val) {
459 : // Create a temporary variable.
460 6: Val = CGF.CreateMemTemp(E->getType(), "tmp");
461 :
462 : // FIXME: volatile
463 6: CGF.EmitAggExpr(E->getSubExpr(), Val, false);
464 : } else
465 45: Visit(E->getSubExpr());
466 :
467 : // Don't make this a live temporary if we're emitting an initializer expr.
37: branch 0 taken
14: branch 1 taken
468 51: if (!IsInitializer)
469 37: CGF.PushCXXTemporary(E->getTemporary(), Val);
470 51: }
471 :
472 : void
473 751: AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
474 751: llvm::Value *Val = DestPtr;
475 :
6: branch 0 taken
745: branch 1 taken
476 751: if (!Val) {
477 : // Create a temporary variable.
478 6: Val = CGF.CreateMemTemp(E->getType(), "tmp");
479 : }
480 :
1: branch 1 taken
750: branch 2 taken
481 751: if (E->requiresZeroInitialization())
482 : EmitNullInitializationToLValue(LValue::MakeAddr(Val,
483 : // FIXME: Qualifiers()?
484 : E->getType().getQualifiers()),
485 1: E->getType());
486 :
487 751: CGF.EmitCXXConstructExpr(Val, E);
488 751: }
489 :
490 37: void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
491 37: llvm::Value *Val = DestPtr;
492 :
5: branch 0 taken
32: branch 1 taken
493 37: if (!Val) {
494 : // Create a temporary variable.
495 5: Val = CGF.CreateMemTemp(E->getType(), "tmp");
496 : }
497 37: CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
498 37: }
499 :
500 3: void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
501 3: llvm::Value *Val = DestPtr;
502 :
1: branch 0 taken
2: branch 1 taken
503 3: if (!Val) {
504 : // Create a temporary variable.
505 1: Val = CGF.CreateMemTemp(E->getType(), "tmp");
506 : }
507 3: LValue LV = LValue::MakeAddr(Val, Qualifiers());
508 3: EmitNullInitializationToLValue(LV, E->getType());
509 3: }
510 :
511 8: void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
512 8: llvm::Value *Val = DestPtr;
513 :
0: branch 0 not taken
8: branch 1 taken
514 8: if (!Val) {
515 : // Create a temporary variable.
516 0: Val = CGF.CreateMemTemp(E->getType(), "tmp");
517 : }
518 8: LValue LV = LValue::MakeAddr(Val, Qualifiers());
519 8: EmitNullInitializationToLValue(LV, E->getType());
520 8: }
521 :
522 : void
523 69: AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
524 : // FIXME: Ignore result?
525 : // FIXME: Are initializers affected by volatile?
0: branch 1 not taken
69: branch 2 taken
526 69: if (isa<ImplicitValueInitExpr>(E)) {
527 0: EmitNullInitializationToLValue(LV, T);
4: branch 2 taken
65: branch 3 taken
528 69: } else if (T->isReferenceType()) {
529 4: RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
530 4: CGF.EmitStoreThroughLValue(RV, LV, T);
0: branch 2 not taken
65: branch 3 taken
531 65: } else if (T->isAnyComplexType()) {
532 0: CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
13: branch 1 taken
52: branch 2 taken
533 65: } else if (CGF.hasAggregateLLVMType(T)) {
534 13: CGF.EmitAnyExpr(E, LV.getAddress(), false);
535 : } else {
536 52: CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
537 : }
538 69: }
539 :
540 28: void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
12: branch 1 taken
16: branch 2 taken
541 28: if (!CGF.hasAggregateLLVMType(T)) {
542 : // For non-aggregates, we can store zero
543 12: llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
544 12: CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
545 : } else {
546 : // Otherwise, just memset the whole thing to zero. This is legal
547 : // because in LLVM, all default initializers are guaranteed to have a
548 : // bit pattern of all zeros.
549 : // FIXME: That isn't true for member pointers!
550 : // There's a potential optimization opportunity in combining
551 : // memsets; that would be easy for arrays, but relatively
552 : // difficult for structures with the current code.
553 16: CGF.EmitMemSetToZero(LV.getAddress(), T);
554 : }
555 28: }
556 :
557 36: void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
558 : #if 0
559 : // FIXME: Assess perf here? Figure out what cases are worth optimizing here
560 : // (Length of globals? Chunks of zeroed-out space?).
561 : //
562 : // If we can, prefer a copy from a global; this is a lot less code for long
563 : // globals, and it's easier for the current optimizers to analyze.
564 : if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
565 : llvm::GlobalVariable* GV =
566 : new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
567 : llvm::GlobalValue::InternalLinkage, C, "");
568 : EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers()));
569 : return;
570 : }
571 : #endif
0: branch 1 not taken
36: branch 2 taken
572 36: if (E->hadArrayRangeDesignator()) {
573 0: CGF.ErrorUnsupported(E, "GNU array range designator extension");
574 : }
575 :
576 : // Handle initialization of an array.
9: branch 3 taken
27: branch 4 taken
577 36: if (E->getType()->isArrayType()) {
578 : const llvm::PointerType *APType =
579 9: cast<llvm::PointerType>(DestPtr->getType());
580 : const llvm::ArrayType *AType =
581 9: cast<llvm::ArrayType>(APType->getElementType());
582 :
583 9: uint64_t NumInitElements = E->getNumInits();
584 :
9: branch 1 taken
0: branch 2 not taken
585 9: if (E->getNumInits() > 0) {
586 9: QualType T1 = E->getType();
587 9: QualType T2 = E->getInit(0)->getType();
0: branch 2 not taken
9: branch 3 taken
588 9: if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
589 0: EmitAggLoadOfLValue(E->getInit(0));
590 0: return;
591 : }
592 : }
593 :
594 9: uint64_t NumArrayElements = AType->getNumElements();
595 9: QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
596 9: ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
597 :
598 : // FIXME: were we intentionally ignoring address spaces and GC attributes?
599 9: Qualifiers Quals = CGF.MakeQualifiers(ElementType);
600 :
37: branch 0 taken
9: branch 1 taken
601 46: for (uint64_t i = 0; i != NumArrayElements; ++i) {
602 37: llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
24: branch 0 taken
13: branch 1 taken
603 37: if (i < NumInitElements)
604 : EmitInitializationToLValue(E->getInit(i),
605 : LValue::MakeAddr(NextVal, Quals),
606 24: ElementType);
607 : else
608 : EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
609 13: ElementType);
610 : }
611 9: return;
612 : }
613 :
27: branch 3 taken
0: branch 4 not taken
614 27: assert(E->getType()->isRecordType() && "Only support structs/unions here!");
615 :
616 : // Do struct initialization; this code just sets each individual member
617 : // to the approprate value. This makes bitfield support automatic;
618 : // the disadvantage is that the generated code is more difficult for
619 : // the optimizer, especially with bitfields.
620 27: unsigned NumInitElements = E->getNumInits();
621 27: RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
622 27: unsigned CurInitVal = 0;
623 :
0: branch 3 not taken
27: branch 4 taken
624 27: if (E->getType()->isUnionType()) {
625 : // Only initialize one field of a union. The field itself is
626 : // specified by the initializer list.
0: branch 1 not taken
0: branch 2 not taken
627 0: if (!E->getInitializedFieldInUnion()) {
628 : // Empty union; we have nothing to do.
629 :
630 : #ifndef NDEBUG
631 : // Make sure that it's really an empty and not a failure of
632 : // semantic analysis.
0: branch 3 not taken
0: branch 4 not taken
633 0: for (RecordDecl::field_iterator Field = SD->field_begin(),
634 0: FieldEnd = SD->field_end();
635 : Field != FieldEnd; ++Field)
0: branch 2 not taken
0: branch 3 not taken
636 0: assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
637 : #endif
638 0: return;
639 : }
640 :
641 : // FIXME: volatility
642 0: FieldDecl *Field = E->getInitializedFieldInUnion();
643 0: LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
644 :
0: branch 0 not taken
0: branch 1 not taken
645 0: if (NumInitElements) {
646 : // Store the initializer into the field
647 0: EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
648 : } else {
649 : // Default-initialize to null
650 0: EmitNullInitializationToLValue(FieldLoc, Field->getType());
651 : }
652 :
653 0: return;
654 : }
655 :
656 : // Here we iterate over the fields; this makes it simpler to both
657 : // default-initialize fields and skip over unnamed fields.
45: branch 3 taken
27: branch 4 taken
658 99: for (RecordDecl::field_iterator Field = SD->field_begin(),
659 27: FieldEnd = SD->field_end();
660 : Field != FieldEnd; ++Field) {
661 : // We're done once we hit the flexible array member
0: branch 4 not taken
45: branch 5 taken
662 45: if (Field->getType()->isIncompleteArrayType())
663 0: break;
664 :
0: branch 2 not taken
45: branch 3 taken
665 45: if (Field->isUnnamedBitfield())
666 0: continue;
667 :
668 : // FIXME: volatility
669 45: LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
670 : // We never generate write-barries for initialized fields.
671 45: LValue::SetObjCNonGC(FieldLoc, true);
42: branch 0 taken
3: branch 1 taken
672 45: if (CurInitVal < NumInitElements) {
673 : // Store the initializer into the field
674 : EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
675 42: Field->getType());
676 : } else {
677 : // We're out of initalizers; default-initialize to null
678 3: EmitNullInitializationToLValue(FieldLoc, Field->getType());
679 : }
680 : }
681 : }
682 :
683 : //===----------------------------------------------------------------------===//
684 : // Entry Points into this File
685 : //===----------------------------------------------------------------------===//
686 :
687 : /// EmitAggExpr - Emit the computation of the specified expression of aggregate
688 : /// type. The result is computed into DestPtr. Note that if DestPtr is null,
689 : /// the value of the aggregate expression is not needed. If VolatileDest is
690 : /// true, DestPtr cannot be 0.
691 : //
692 : // FIXME: Take Qualifiers object.
693 : void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
694 : bool VolatileDest, bool IgnoreResult,
695 : bool IsInitializer,
696 1110: bool RequiresGCollection) {
697 : assert(E && hasAggregateLLVMType(E->getType()) &&
1110: branch 0 taken
0: branch 1 not taken
1110: branch 4 taken
0: branch 5 not taken
698 1110: "Invalid aggregate expression to emit");
699 : assert ((DestPtr != 0 || VolatileDest == false)
107: branch 0 taken
1003: branch 1 taken
0: branch 2 not taken
107: branch 3 taken
700 1217: && "volatile aggregate can't be 0");
701 :
702 : AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
703 : RequiresGCollection)
704 1110: .Visit(const_cast<Expr*>(E));
705 1110: }
706 :
707 18: LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
18: branch 2 taken
0: branch 3 not taken
708 18: assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
709 18: Qualifiers Q = MakeQualifiers(E->getType());
710 18: llvm::Value *Temp = CreateMemTemp(E->getType());
711 18: EmitAggExpr(E, Temp, Q.hasVolatile());
712 18: return LValue::MakeAddr(Temp, Q);
713 : }
714 :
715 0: void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
0: branch 2 not taken
0: branch 3 not taken
716 0: assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
717 :
718 0: EmitMemSetToZero(DestPtr, Ty);
719 0: }
720 :
721 : void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
722 : llvm::Value *SrcPtr, QualType Ty,
723 204: bool isVolatile) {
204: branch 2 taken
0: branch 3 not taken
724 204: assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
725 :
726 : // Aggregate assignment turns into llvm.memcpy. This is almost valid per
727 : // C99 6.5.16.1p3, which states "If the value being stored in an object is
728 : // read from another object that overlaps in anyway the storage of the first
729 : // object, then the overlap shall be exact and the two objects shall have
730 : // qualified or unqualified versions of a compatible type."
731 : //
732 : // memcpy is not defined if the source and destination pointers are exactly
733 : // equal, but other compilers do this optimization, and almost every memcpy
734 : // implementation handles this case safely. If there is a libc that does not
735 : // safely handle this, we can add a target hook.
736 204: const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
204: branch 1 taken
0: branch 2 not taken
737 204: if (DestPtr->getType() != BP)
738 204: DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
204: branch 1 taken
0: branch 2 not taken
739 204: if (SrcPtr->getType() != BP)
740 204: SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
741 :
742 : // Get size and alignment info for this aggregate.
743 204: std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
744 :
745 : // FIXME: Handle variable sized types.
746 : const llvm::Type *IntPtr =
747 204: llvm::IntegerType::get(VMContext, LLVMPointerWidth);
748 :
749 : // FIXME: If we have a volatile struct, the optimizer can remove what might
750 : // appear to be `extra' memory ops:
751 : //
752 : // volatile struct { int i; } a, b;
753 : //
754 : // int main() {
755 : // a = b;
756 : // a = b;
757 : // }
758 : //
759 : // we need to use a differnt call here. We use isVolatile to indicate when
760 : // either the source or the destination is volatile.
761 : Builder.CreateCall4(CGM.getMemCpyFn(),
762 : DestPtr, SrcPtr,
763 : // TypeInfo.first describes size in bits.
764 : llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
765 : llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
766 204: TypeInfo.second/8));
767 204: }
Generated: 2010-02-10 01:31 by zcov