aboutsummaryrefslogtreecommitdiff
path: root/CodeGen/CGExprAgg.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-08-24 02:22:53 +0000
committerChris Lattner <sabre@nondot.org>2007-08-24 02:22:53 +0000
commit566b6ce741c742cc3f8cb85e2376ec4a3490ff5f (patch)
tree0edc54ea9532b95cb385f4218bbad8522c52db4d /CodeGen/CGExprAgg.cpp
parentd0b1203b1c982be34a56199c59c53ae15a953667 (diff)
rename two files.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41350 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CGExprAgg.cpp')
-rw-r--r--CodeGen/CGExprAgg.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/CodeGen/CGExprAgg.cpp b/CodeGen/CGExprAgg.cpp
new file mode 100644
index 0000000000..17e11a1fe4
--- /dev/null
+++ b/CodeGen/CGExprAgg.cpp
@@ -0,0 +1,186 @@
+//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit Aggregate Expr nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/AST.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Support/Compiler.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+// Aggregate Expression Emitter
+//===----------------------------------------------------------------------===//
+
+namespace {
+class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
+ CodeGenFunction &CGF;
+ llvm::Value *DestPtr;
+ bool VolatileDest;
+public:
+ AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
+ : CGF(cgf), DestPtr(destPtr), VolatileDest(volatileDest) {
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Utilities
+ //===--------------------------------------------------------------------===//
+
+ /// EmitAggLoadOfLValue - Given an expression with aggregate type that
+ /// represents a value lvalue, this method emits the address of the lvalue,
+ /// then loads the result into DestPtr.
+ void EmitAggLoadOfLValue(const Expr *E);
+
+
+ //===--------------------------------------------------------------------===//
+ // Visitor Methods
+ //===--------------------------------------------------------------------===//
+
+ void VisitStmt(Stmt *S) {
+ fprintf(stderr, "Unimplemented agg expr!\n");
+ S->dump();
+ }
+ void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
+
+ // l-values.
+ void VisitDeclRefExpr(DeclRefExpr *DRE) { return EmitAggLoadOfLValue(DRE); }
+ // case Expr::ArraySubscriptExprClass:
+
+ // Operators.
+ // case Expr::UnaryOperatorClass:
+ // case Expr::ImplicitCastExprClass:
+ // case Expr::CastExprClass:
+ // case Expr::CallExprClass:
+ void VisitBinaryOperator(const BinaryOperator *BO);
+ void VisitBinAssign(const BinaryOperator *E);
+
+
+ void VisitConditionalOperator(const ConditionalOperator *CO);
+ // case Expr::ChooseExprClass:
+};
+} // end anonymous namespace.
+
+//===----------------------------------------------------------------------===//
+// Utilities
+//===----------------------------------------------------------------------===//
+
+/// EmitAggLoadOfLValue - Given an expression with aggregate type that
+/// represents a value lvalue, this method emits the address of the lvalue,
+/// then loads the result into DestPtr.
+void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
+ LValue LV = CGF.EmitLValue(E);
+ assert(LV.isSimple() && "Can't have aggregate bitfield, vector, etc");
+ llvm::Value *SrcPtr = LV.getAddress();
+
+ // If the result is ignored, don't copy from the value.
+ if (DestPtr == 0)
+ // FIXME: If the source is volatile, we must read from it.
+ return;
+
+ CGF.EmitAggregateCopy(DestPtr, SrcPtr, E->getType());
+}
+
+//===----------------------------------------------------------------------===//
+// Visitor Methods
+//===----------------------------------------------------------------------===//
+
+void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
+ fprintf(stderr, "Unimplemented aggregate binary expr!\n");
+ E->dump();
+}
+
+void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+ assert(E->getLHS()->getType().getCanonicalType() ==
+ E->getRHS()->getType().getCanonicalType() && "Invalid assignment");
+ LValue LHS = CGF.EmitLValue(E->getLHS());
+
+ // Codegen the RHS so that it stores directly into the LHS.
+ CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
+
+ // If the result of the assignment is used, copy the RHS there also.
+ if (DestPtr) {
+ assert(0 && "FIXME: Chained agg assignment not implemented yet");
+ }
+}
+
+void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
+ llvm::BasicBlock *LHSBlock = new llvm::BasicBlock("cond.?");
+ llvm::BasicBlock *RHSBlock = new llvm::BasicBlock("cond.:");
+ llvm::BasicBlock *ContBlock = new llvm::BasicBlock("cond.cont");
+
+ llvm::Value *Cond = CGF.EvaluateExprAsBool(E->getCond());
+ CGF.Builder.CreateCondBr(Cond, LHSBlock, RHSBlock);
+
+ CGF.EmitBlock(LHSBlock);
+
+ // Handle the GNU extension for missing LHS.
+ assert(E->getLHS() && "Must have LHS for aggregate value");
+
+ Visit(E->getLHS());
+ CGF.Builder.CreateBr(ContBlock);
+ LHSBlock = CGF.Builder.GetInsertBlock();
+
+ CGF.EmitBlock(RHSBlock);
+
+ Visit(E->getRHS());
+ CGF.Builder.CreateBr(ContBlock);
+ RHSBlock = CGF.Builder.GetInsertBlock();
+
+ CGF.EmitBlock(ContBlock);
+}
+
+//===----------------------------------------------------------------------===//
+// Entry Points into this File
+//===----------------------------------------------------------------------===//
+
+/// EmitAggExpr - Emit the computation of the specified expression of
+/// aggregate type. The result is computed into DestPtr. Note that if
+/// DestPtr is null, the value of the aggregate expression is not needed.
+void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
+ bool VolatileDest) {
+ assert(E && hasAggregateLLVMType(E->getType()) &&
+ "Invalid aggregate expression to emit");
+
+ AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
+}
+
+
+// FIXME: Handle volatility!
+void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
+ llvm::Value *SrcPtr, QualType Ty) {
+ assert(!Ty->isComplexType() && "Shouldn't happen for complex");
+
+ // Aggregate assignment turns into llvm.memcpy.
+ const llvm::Type *BP = llvm::PointerType::get(llvm::Type::Int8Ty);
+ if (DestPtr->getType() != BP)
+ DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
+ if (SrcPtr->getType() != BP)
+ SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+
+ // Get size and alignment info for this aggregate.
+ std::pair<uint64_t, unsigned> TypeInfo =
+ getContext().getTypeInfo(Ty, SourceLocation());
+
+ // FIXME: Handle variable sized types.
+ const llvm::Type *IntPtr = llvm::IntegerType::get(LLVMPointerWidth);
+
+ llvm::Value *MemCpyOps[4] = {
+ DestPtr, SrcPtr,
+ llvm::ConstantInt::get(IntPtr, TypeInfo.first),
+ llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
+ };
+
+ Builder.CreateCall(CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
+}