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