blob: 84a69b1d8c12ccc13f54e39712d029ec650e8cd3 [file] [log] [blame]
Chris Lattner78ed8402007-08-10 20:13:28 +00001//===--- CGAggExpr.cpp - Emit LLVM Code from Aggregate Expressions --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source 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"
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000015#include "CodeGenModule.h"
16#include "clang/AST/AST.h"
17#include "llvm/Constants.h"
18#include "llvm/Function.h"
Chris Lattnerb50e3902007-08-21 04:25:47 +000019#include "llvm/Support/Compiler.h"
Chris Lattner78ed8402007-08-10 20:13:28 +000020using namespace clang;
21using namespace CodeGen;
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000022
Chris Lattnerb50e3902007-08-21 04:25:47 +000023//===----------------------------------------------------------------------===//
24// Aggregate Expression Emitter
25//===----------------------------------------------------------------------===//
26
27namespace {
28class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
29 CodeGenFunction &CGF;
30 llvm::Value *DestPtr;
31 bool VolatileDest;
32public:
33 AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
34 : CGF(cgf), DestPtr(destPtr), VolatileDest(volatileDest) {
35 }
36
Chris Lattnera7300102007-08-21 04:59:27 +000037 typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
38
39 //===--------------------------------------------------------------------===//
40 // Utilities
41 //===--------------------------------------------------------------------===//
42
Chris Lattnerb50e3902007-08-21 04:25:47 +000043 /// EmitAggLoadOfLValue - Given an expression with aggregate type that
44 /// represents a value lvalue, this method emits the address of the lvalue,
45 /// then loads the result into DestPtr.
46 void EmitAggLoadOfLValue(const Expr *E);
47
Chris Lattnera7300102007-08-21 04:59:27 +000048
49 //===--------------------------------------------------------------------===//
50 // Visitor Methods
51 //===--------------------------------------------------------------------===//
52
Chris Lattnerb50e3902007-08-21 04:25:47 +000053 void VisitStmt(Stmt *S) {
54 fprintf(stderr, "Unimplemented agg expr!\n");
55 S->dump();
56 }
57 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
58
59 // l-values.
60 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
61 // case Expr::ArraySubscriptExprClass:
62
63 // Operators.
64 // case Expr::UnaryOperatorClass:
65 // case Expr::ImplicitCastExprClass:
66 // case Expr::CastExprClass:
67 // case Expr::CallExprClass:
68 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner76cb1892007-08-21 04:43:17 +000069 void VisitBinAssign(const BinaryOperator *E);
Chris Lattnerb50e3902007-08-21 04:25:47 +000070
71
72 void VisitConditionalOperator(const ConditionalOperator *CO);
73 // case Expr::ChooseExprClass:
74};
75} // end anonymous namespace.
76
Chris Lattnera7300102007-08-21 04:59:27 +000077//===----------------------------------------------------------------------===//
78// Utilities
79//===----------------------------------------------------------------------===//
Chris Lattnerb50e3902007-08-21 04:25:47 +000080
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000081/// EmitAggLoadOfLValue - Given an expression with aggregate type that
82/// represents a value lvalue, this method emits the address of the lvalue,
83/// then loads the result into DestPtr.
Chris Lattnerb50e3902007-08-21 04:25:47 +000084void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
85 LValue LV = CGF.EmitLValue(E);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000086 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
87 llvm::Value *SrcPtr = LV.getAddress();
88
89 // If the result is ignored, don't copy from the value.
90 if (DestPtr == 0)
91 // FIXME: If the source is volatile, we must read from it.
92 return;
93
Chris Lattnerb50e3902007-08-21 04:25:47 +000094 CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000095}
96
Chris Lattnera7300102007-08-21 04:59:27 +000097//===----------------------------------------------------------------------===//
98// Visitor Methods
99//===----------------------------------------------------------------------===//
100
Chris Lattnerb50e3902007-08-21 04:25:47 +0000101void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner76cb1892007-08-21 04:43:17 +0000102 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
103 E->dump();
Chris Lattnera7300102007-08-21 04:59:27 +0000104}
105
Chris Lattner76cb1892007-08-21 04:43:17 +0000106void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000107 assert(E->getLHS()->getType().getCanonicalType() ==
108 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattnerb50e3902007-08-21 04:25:47 +0000109 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000110
111 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000112 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000113
114 // If the result of the assignment is used, copy the RHS there also.
115 if (DestPtr) {
116 assert(0 && "FIXME: Chained agg assignment not implemented yet");
117 }
118}
119
Chris Lattnerb50e3902007-08-21 04:25:47 +0000120void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000121 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
122 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
123 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
124
Chris Lattnerb50e3902007-08-21 04:25:47 +0000125 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
126 CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000127
Chris Lattnerb50e3902007-08-21 04:25:47 +0000128 CGF.EmitBlock(LHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000129
130 // Handle the GNU extension for missing LHS.
131 assert(E->getLHS() && "Must have LHS for aggregate value");
132
Chris Lattner55165ba2007-08-21 05:02:10 +0000133 Visit(E->getLHS());
Chris Lattnerb50e3902007-08-21 04:25:47 +0000134 CGF.Builder.CreateBr(ContBlock);
Chris Lattner55165ba2007-08-21 05:02:10 +0000135 LHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000136
Chris Lattnerb50e3902007-08-21 04:25:47 +0000137 CGF.EmitBlock(RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000138
Chris Lattner55165ba2007-08-21 05:02:10 +0000139 Visit(E->getRHS());
Chris Lattnerb50e3902007-08-21 04:25:47 +0000140 CGF.Builder.CreateBr(ContBlock);
141 RHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000142
Chris Lattnerb50e3902007-08-21 04:25:47 +0000143 CGF.EmitBlock(ContBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000144}
Chris Lattnera7300102007-08-21 04:59:27 +0000145
146//===----------------------------------------------------------------------===//
147// Entry Points into this File
148//===----------------------------------------------------------------------===//
149
150/// EmitAggExpr - Emit the computation of the specified expression of
151/// aggregate type. The result is computed into DestPtr. Note that if
152/// DestPtr is null, the value of the aggregate expression is not needed.
153void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
154 bool VolatileDest) {
155 assert(E && hasAggregateLLVMType(E->getType()) &&
156 "Invalid aggregate expression to emit");
157
158 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
159}
160
161
162// FIXME: Handle volatility!
163void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
164 llvm::Value *SrcPtr, QualType Ty) {
165 // Don't use memcpy for complex numbers.
166 if (Ty->isComplexType()) {
167 llvm::Value *Real, *Imag;
168 EmitLoadOfComplex(SrcPtr, Real, Imag);
169 EmitStoreOfComplex(Real, Imag, DestPtr);
170 return;
171 }
172
173 // Aggregate assignment turns into llvm.memcpy.
174 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
175 if (DestPtr->getType() != BP)
176 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
177 if (SrcPtr->getType() != BP)
178 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
179
180 // Get size and alignment info for this aggregate.
181 std::pair<uint64_t, unsigned> TypeInfo =
182 getContext().getTypeInfo(Ty, SourceLocation());
183
184 // FIXME: Handle variable sized types.
185 const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
186
187 llvm::Value *MemCpyOps[4] = {
188 DestPtr, SrcPtr,
189 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
190 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
191 };
192
193 Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
194}