blob: 8ae6f695e87374a3e4874c3ff47471b3bb91889e [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;
Chris Lattner41b1fca2007-08-26 23:13:56 +000030 llvm::LLVMBuilder &Builder;
Chris Lattnerb50e3902007-08-21 04:25:47 +000031 llvm::Value *DestPtr;
32 bool VolatileDest;
33public:
34 AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
Chris Lattner41b1fca2007-08-26 23:13:56 +000035 : CGF(cgf), Builder(CGF.Builder),
36 DestPtr(destPtr), VolatileDest(volatileDest) {
Chris Lattnerb50e3902007-08-21 04:25:47 +000037 }
38
Chris Lattnera7300102007-08-21 04:59:27 +000039 //===--------------------------------------------------------------------===//
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 Lattner41b1fca2007-08-26 23:13:56 +000048 void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
49 QualType EltTy);
Chris Lattnera7300102007-08-21 04:59:27 +000050
51 //===--------------------------------------------------------------------===//
52 // Visitor Methods
53 //===--------------------------------------------------------------------===//
54
Chris Lattnerb50e3902007-08-21 04:25:47 +000055 void VisitStmt(Stmt *S) {
56 fprintf(stderr, "Unimplemented agg expr!\n");
57 S->dump();
58 }
59 void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
60
61 // l-values.
62 void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
63 // case Expr::ArraySubscriptExprClass:
64
65 // Operators.
66 // case Expr::UnaryOperatorClass:
67 // case Expr::ImplicitCastExprClass:
68 // case Expr::CastExprClass:
69 // case Expr::CallExprClass:
70 void VisitBinaryOperator(const BinaryOperator *BO);
Chris Lattner76cb1892007-08-21 04:43:17 +000071 void VisitBinAssign(const BinaryOperator *E);
Chris Lattnerb50e3902007-08-21 04:25:47 +000072
73
74 void VisitConditionalOperator(const ConditionalOperator *CO);
75 // case Expr::ChooseExprClass:
76};
77} // end anonymous namespace.
78
Chris Lattnera7300102007-08-21 04:59:27 +000079//===----------------------------------------------------------------------===//
80// Utilities
81//===----------------------------------------------------------------------===//
Chris Lattnerb50e3902007-08-21 04:25:47 +000082
Chris Lattner41b1fca2007-08-26 23:13:56 +000083void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
84 llvm::Value *SrcPtr, QualType Ty) {
85 assert(!Ty->isComplexType() && "Shouldn't happen for complex");
86
87 // Aggregate assignment turns into llvm.memcpy.
88 const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
89 if (DestPtr->getType() != BP)
90 DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
91 if (SrcPtr->getType() != BP)
92 SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
93
94 // Get size and alignment info for this aggregate.
95 std::pair<uint64_t, unsigned> TypeInfo =
96 CGF.getContext().getTypeInfo(Ty, SourceLocation());
97
98 // FIXME: Handle variable sized types.
99 const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
100
101 llvm::Value *MemCpyOps[4] = {
102 DestPtr, SrcPtr,
103 llvm::ConstantInt::get(IntPtr, TypeInfo.first),
104 llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
105 };
106
107 Builder.CreateCall(CGF.CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
108}
109
110
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000111/// EmitAggLoadOfLValue - Given an expression with aggregate type that
112/// represents a value lvalue, this method emits the address of the lvalue,
113/// then loads the result into DestPtr.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000114void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
115 LValue LV = CGF.EmitLValue(E);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000116 assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
117 llvm::Value *SrcPtr = LV.getAddress();
118
119 // If the result is ignored, don't copy from the value.
120 if (DestPtr == 0)
121 // FIXME: If the source is volatile, we must read from it.
122 return;
123
Chris Lattner41b1fca2007-08-26 23:13:56 +0000124 EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000125}
126
Chris Lattnera7300102007-08-21 04:59:27 +0000127//===----------------------------------------------------------------------===//
128// Visitor Methods
129//===----------------------------------------------------------------------===//
130
Chris Lattnerb50e3902007-08-21 04:25:47 +0000131void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
Chris Lattner76cb1892007-08-21 04:43:17 +0000132 fprintf(stderr, "Unimplemented aggregate binary expr!\n");
133 E->dump();
Chris Lattnera7300102007-08-21 04:59:27 +0000134}
135
Chris Lattner76cb1892007-08-21 04:43:17 +0000136void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000137 assert(E->getLHS()->getType().getCanonicalType() ==
138 E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
Chris Lattnerb50e3902007-08-21 04:25:47 +0000139 LValue LHS = CGF.EmitLValue(E->getLHS());
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000140
141 // Codegen the RHS so that it stores directly into the LHS.
Chris Lattnerb50e3902007-08-21 04:25:47 +0000142 CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000143
144 // If the result of the assignment is used, copy the RHS there also.
145 if (DestPtr) {
146 assert(0 && "FIXME: Chained agg assignment not implemented yet");
147 }
148}
149
Chris Lattnerb50e3902007-08-21 04:25:47 +0000150void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000151 llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
152 llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
153 llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
154
Chris Lattnerb50e3902007-08-21 04:25:47 +0000155 llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
Chris Lattner41b1fca2007-08-26 23:13:56 +0000156 Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000157
Chris Lattnerb50e3902007-08-21 04:25:47 +0000158 CGF.EmitBlock(LHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000159
160 // Handle the GNU extension for missing LHS.
161 assert(E->getLHS() && "Must have LHS for aggregate value");
162
Chris Lattner55165ba2007-08-21 05:02:10 +0000163 Visit(E->getLHS());
Chris Lattner41b1fca2007-08-26 23:13:56 +0000164 Builder.CreateBr(ContBlock);
165 LHSBlock = Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000166
Chris Lattnerb50e3902007-08-21 04:25:47 +0000167 CGF.EmitBlock(RHSBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000168
Chris Lattner55165ba2007-08-21 05:02:10 +0000169 Visit(E->getRHS());
Chris Lattner41b1fca2007-08-26 23:13:56 +0000170 Builder.CreateBr(ContBlock);
171 RHSBlock = Builder.GetInsertBlock();
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000172
Chris Lattnerb50e3902007-08-21 04:25:47 +0000173 CGF.EmitBlock(ContBlock);
Chris Lattnerbdb8ffb2007-08-11 00:04:45 +0000174}
Chris Lattnera7300102007-08-21 04:59:27 +0000175
176//===----------------------------------------------------------------------===//
177// Entry Points into this File
178//===----------------------------------------------------------------------===//
179
180/// EmitAggExpr - Emit the computation of the specified expression of
181/// aggregate type. The result is computed into DestPtr. Note that if
182/// DestPtr is null, the value of the aggregate expression is not needed.
183void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
184 bool VolatileDest) {
185 assert(E && hasAggregateLLVMType(E->getType()) &&
186 "Invalid aggregate expression to emit");
187
188 AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
189}