blob: 17e11a1fe4c0f0c04eaa4d3bdbbef03c067ddcea [file] [log] [blame]
Chris Lattner820dce82007-08-24 02:22:53 +00001//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
Chris Lattner78ed8402007-08-10 20:13:28 +00002//
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 //===--------------------------------------------------------------------===//
38 // Utilities
39 //===--------------------------------------------------------------------===//
40
Chris Lattnerb50e3902007-08-21 04:25:47 +000041 /// EmitAggLoadOfLValue - Given an expression with aggregate type that
42 /// represents a value lvalue, this method emits the address of the lvalue,
43 /// then loads the result into DestPtr.
44 void EmitAggLoadOfLValue(const Expr *E);
45
Chris Lattnera7300102007-08-21 04:59:27 +000046
47 //===--------------------------------------------------------------------===//
48 // Visitor Methods
49 //===--------------------------------------------------------------------===//
50
Chris Lattnerb50e3902007-08-21 04:25:47 +000051 void VisitStmt(Stmt *S) {
52 fprintf(stderr, "Unimplemented agg expr!\n");
53 S->dump();
54 }
55 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
56
57 // l-values.
58 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
59 // case Expr::ArraySubscriptExprClass:
60
61 // Operators.
62 // case Expr::UnaryOperatorClass:
63 // case Expr::ImplicitCastExprClass:
64 // case Expr::CastExprClass:
65 // case Expr::CallExprClass:
66 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner76cb1892007-08-21 04:43:17 +000067 void VisitBinAssign(const BinaryOperator *E);
Chris Lattnerb50e3902007-08-21 04:25:47 +000068
69
70 void VisitConditionalOperator(const ConditionalOperator *CO);
71 // case Expr::ChooseExprClass:
72};
73} // end anonymous namespace.
74
Chris Lattnera7300102007-08-21 04:59:27 +000075//===----------------------------------------------------------------------===//
76// Utilities
77//===----------------------------------------------------------------------===//
Chris Lattnerb50e3902007-08-21 04:25:47 +000078
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000079/// EmitAggLoadOfLValue - Given an expression with aggregate type that
80/// represents a value lvalue, this method emits the address of the lvalue,
81/// then loads the result into DestPtr.
Chris Lattnerb50e3902007-08-21 04:25:47 +000082void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
83 LValue LV = CGF.EmitLValue(E);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000084 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
85 llvm::Value *SrcPtr = LV.getAddress();
86
87 // If the result is ignored, don't copy from the value.
88 if (DestPtr == 0)
89 // FIXME: If the source is volatile, we must read from it.
90 return;
91
Chris Lattnerb50e3902007-08-21 04:25:47 +000092 CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +000093}
94
Chris Lattnera7300102007-08-21 04:59:27 +000095//===----------------------------------------------------------------------===//
96// Visitor Methods
97//===----------------------------------------------------------------------===//
98
Chris Lattnerb50e3902007-08-21 04:25:47 +000099void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner76cb1892007-08-21 04:43:17 +0000100 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
101 E->dump();
Chris Lattnera7300102007-08-21 04:59:27 +0000102}
103
Chris Lattner76cb1892007-08-21 04:43:17 +0000104void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000105 assert(E->getLHS()->getType().getCanonicalType() ==
106 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattnerb50e3902007-08-21 04:25:47 +0000107 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000108
109 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000110 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000111
112 // If the result of the assignment is used, copy the RHS there also.
113 if (DestPtr) {
114 assert(0 && "FIXME: Chained agg assignment not implemented yet");
115 }
116}
117
Chris Lattnerb50e3902007-08-21 04:25:47 +0000118void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000119 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
120 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
121 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
122
Chris Lattnerb50e3902007-08-21 04:25:47 +0000123 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
124 CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000125
Chris Lattnerb50e3902007-08-21 04:25:47 +0000126 CGF.EmitBlock(LHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000127
128 // Handle the GNU extension for missing LHS.
129 assert(E->getLHS() && "Must have LHS for aggregate value");
130
Chris Lattner55165ba2007-08-21 05:02:10 +0000131 Visit(E->getLHS());
Chris Lattnerb50e3902007-08-21 04:25:47 +0000132 CGF.Builder.CreateBr(ContBlock);
Chris Lattner55165ba2007-08-21 05:02:10 +0000133 LHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000134
Chris Lattnerb50e3902007-08-21 04:25:47 +0000135 CGF.EmitBlock(RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000136
Chris Lattner55165ba2007-08-21 05:02:10 +0000137 Visit(E->getRHS());
Chris Lattnerb50e3902007-08-21 04:25:47 +0000138 CGF.Builder.CreateBr(ContBlock);
139 RHSBlock = CGF.Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000140
Chris Lattnerb50e3902007-08-21 04:25:47 +0000141 CGF.EmitBlock(ContBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000142}
Chris Lattnera7300102007-08-21 04:59:27 +0000143
144//===----------------------------------------------------------------------===//
145// Entry Points into this File
146//===----------------------------------------------------------------------===//
147
148/// EmitAggExpr - Emit the computation of the specified expression of
149/// aggregate type. The result is computed into DestPtr. Note that if
150/// DestPtr is null, the value of the aggregate expression is not needed.
151void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
152 bool VolatileDest) {
153 assert(E && hasAggregateLLVMType(E->getType()) &&
154 "Invalid aggregate expression to emit");
155
156 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
157}
158
159
160// FIXME: Handle volatility!
161void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
162 llvm::Value *SrcPtr, QualType Ty) {
Chris Lattner1cd8f5c2007-08-21 17:28:34 +0000163 assert(!Ty->isComplexType() && "Shouldn't happen for complex");
Chris Lattnera7300102007-08-21 04:59:27 +0000164
165 // Aggregate assignment turns into llvm.memcpy.
166 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
167 if (DestPtr->getType() != BP)
168 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
169 if (SrcPtr->getType() != BP)
170 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
171
172 // Get size and alignment info for this aggregate.
173 std::pair<uint64_t, unsigned> TypeInfo =
174 getContext().getTypeInfo(Ty, SourceLocation());
175
176 // FIXME: Handle variable sized types.
177 const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
178
179 llvm::Value *MemCpyOps[4] = {
180 DestPtr, SrcPtr,
181 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
182 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
183 };
184
185 Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
186}