00001
00002
00003
00004
00005
00006
00007
00008
00009
00014
00015
00016 #include "CodeGenRoutine.h"
00017 #include "comma/ast/Expr.h"
00018 #include "comma/ast/Stmt.h"
00019
00020 using namespace comma;
00021 using llvm::dyn_cast;
00022 using llvm::cast;
00023 using llvm::isa;
00024
00025 namespace {
00026
00027 class AssignmentEmitter {
00028
00029 public:
00030 AssignmentEmitter(CodeGenRoutine &CGR)
00031 : CGR(CGR), Builder(CGR.getSRFrame()->getIRBuilder()) { }
00032
00034 void emit(AssignmentStmt *assignment);
00035
00036 private:
00038 CodeGenRoutine &CGR;
00039
00041 llvm::IRBuilder<> &Builder;
00042
00044 SRFrame *frame() { return CGR.getSRFrame(); }
00045
00047 void emitAssignment(DeclRefExpr *lhs, Expr *rhs);
00048 void emitAssignment(SelectedExpr *lhs, Expr *rhs);
00049 void emitAssignment(DereferenceExpr *lhs, Expr *rhs);
00050 void emitAssignment(IndexedArrayExpr *lhs, Expr *rhs);
00051 };
00052
00053 }
00054
00055 void AssignmentEmitter::emitAssignment(DeclRefExpr *lhs, Expr *rhs)
00056 {
00057 Type *targetTy = CGR.resolveType(lhs->getType());
00058 ValueDecl *lhsDecl = lhs->getDeclaration();
00059 llvm::Value *target = frame()->lookup(lhsDecl, activation::Slot);
00060
00061 if (targetTy->isCompositeType()) {
00062
00063 CGR.emitCompositeExpr(rhs, target, false);
00064 }
00065 else if (targetTy->isFatAccessType()) {
00066
00067 llvm::Value *source = CGR.emitValue(rhs).first();
00068 Builder.CreateStore(Builder.CreateLoad(source), target);
00069 }
00070 else {
00071
00072 llvm::Value *source = CGR.emitValue(rhs).first();
00073 Builder.CreateStore(source, target);
00074 }
00075 }
00076
00077 void AssignmentEmitter::emitAssignment(SelectedExpr *lhs, Expr *rhs)
00078 {
00079
00080
00081
00082 llvm::Value *target = CGR.emitSelectedRef(lhs).first();
00083 Type *targetTy = CGR.resolveType(lhs->getType());
00084 if (targetTy->isCompositeType())
00085 CGR.emitCompositeExpr(rhs, target, false);
00086 else if (targetTy->isFatAccessType()) {
00087 llvm::Value *source = CGR.emitValue(rhs).first();
00088 Builder.CreateStore(Builder.CreateLoad(source), target);
00089 }
00090 else {
00091 llvm::Value *source = CGR.emitValue(rhs).first();
00092 Builder.CreateStore(source, target);
00093 }
00094 }
00095
00096 void AssignmentEmitter::emitAssignment(DereferenceExpr *lhs, Expr *rhs)
00097 {
00098 AccessType *prefixTy = lhs->getPrefixType();
00099 llvm::Value *target = CGR.emitValue(lhs->getPrefix()).first();
00100
00101
00102
00103 if (prefixTy->isFatAccessType()) {
00104 target = Builder.CreateStructGEP(target, 0);
00105 target = Builder.CreateLoad(target);
00106 }
00107
00108
00109 Type *targetTy = CGR.resolveType(lhs->getType());
00110 CGR.emitNullAccessCheck(target, lhs->getLocation());
00111 if (targetTy->isCompositeType())
00112 CGR.emitCompositeExpr(rhs, target, false);
00113 else {
00114 llvm::Value *source = CGR.emitValue(rhs).first();
00115 Builder.CreateStore(source, target);
00116 }
00117 }
00118
00119 void AssignmentEmitter::emitAssignment(IndexedArrayExpr *lhs, Expr *rhs)
00120 {
00121
00122 CValue ptr = CGR.emitIndexedArrayRef(lhs);
00123
00124 if (ptr.isSimple()) {
00125 llvm::Value *target = ptr.first();
00126 llvm::Value *source = CGR.emitValue(rhs).first();
00127 Builder.CreateStore(source, target);
00128 }
00129 else if (ptr.isAggregate()) {
00130 llvm::Value *target = ptr.first();
00131 CGR.emitCompositeExpr(rhs, target, false);
00132 }
00133 else {
00134 assert(ptr.isFat());
00135 llvm::Value *target = ptr.first();
00136 llvm::Value *source = CGR.emitValue(rhs).first();
00137 Builder.CreateStore(Builder.CreateLoad(source), target);
00138 }
00139 }
00140
00141 void AssignmentEmitter::emit(AssignmentStmt *stmt)
00142 {
00143 Expr *lhs = stmt->getTarget();
00144 Expr *rhs = stmt->getAssignedExpr();
00145
00146
00147 lhs = lhs->ignoreInjPrj();
00148
00149 #define DISPATCH(KIND, LHS, RHS) \
00150 Ast::AST_ ## KIND: \
00151 emitAssignment(cast<KIND>(LHS), RHS); \
00152 break
00153
00154 switch (lhs->getKind()) {
00155
00156 default:
00157 assert(false && "Cannot codegen assignment!");
00158 break;
00159
00160 case DISPATCH(DeclRefExpr, lhs, rhs);
00161 case DISPATCH(SelectedExpr, lhs, rhs);
00162 case DISPATCH(DereferenceExpr, lhs, rhs);
00163 case DISPATCH(IndexedArrayExpr, lhs, rhs);
00164 }
00165
00166 #undef DISPATCH
00167 }
00168
00169
00170
00171
00172 void CodeGenRoutine::emitAssignmentStmt(AssignmentStmt *stmt)
00173 {
00174 AssignmentEmitter emitter(*this);
00175 emitter.emit(stmt);
00176 }
00177