This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 //===-- codegen/CodeGenAssign.cpp ----------------------------- -*- C++ -*-===// 00002 // 00003 // This file is distributed under the MIT license. See LICENSE.txt for details. 00004 // 00005 // Copyright (C) 2010, Stephen Wilson 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 } // end anonymous namespace. 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 // Evaluate the rhs into the storage provided by the lhs. 00063 CGR.emitCompositeExpr(rhs, target, false); 00064 } 00065 else if (targetTy->isFatAccessType()) { 00066 // Load the pointer to the fat access struct and store into the target. 00067 llvm::Value *source = CGR.emitValue(rhs).first(); 00068 Builder.CreateStore(Builder.CreateLoad(source), target); 00069 } 00070 else { 00071 // The lhs is a simple variable reference. Just emit and store. 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 // If the type of the selected component is composite evaluate the rhs into 00080 // the storage provided by the lhs. It is a fat access type then store into 00081 // the data pointer. Otherwise, simply store the lhs. 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 // If the prefix is a fat access type extract the first component (the 00102 // pointer to the data). 00103 if (prefixTy->isFatAccessType()) { 00104 target = Builder.CreateStructGEP(target, 0); 00105 target = Builder.CreateLoad(target); 00106 } 00107 00108 // Check that the target is not null and emit the rhs. 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 // Get a reference to the needed component and store. 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 // Remove any layers of inj/prj expressions from the left hand side. 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 // Public API for this file. 00171 00172 void CodeGenRoutine::emitAssignmentStmt(AssignmentStmt *stmt) 00173 { 00174 AssignmentEmitter emitter(*this); 00175 emitter.emit(stmt); 00176 } 00177