00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BoundsEmitter.h"
00010 #include "CGContext.h"
00011 #include "CodeGenRoutine.h"
00012 #include "CodeGenTypes.h"
00013 #include "CommaRT.h"
00014 #include "SRInfo.h"
00015 #include "comma/ast/AttribExpr.h"
00016 #include "comma/ast/Decl.h"
00017 #include "comma/ast/Expr.h"
00018 #include "comma/ast/Pragma.h"
00019 #include "comma/ast/RangeAttrib.h"
00020 #include "comma/ast/Stmt.h"
00021 #include "comma/codegen/Mangle.h"
00022
00023 #include "llvm/Analysis/Verifier.h"
00024
00025 using namespace comma;
00026
00027 using llvm::dyn_cast;
00028 using llvm::dyn_cast_or_null;
00029 using llvm::cast;
00030 using llvm::isa;
00031
00032 CodeGenRoutine::CodeGenRoutine(CGContext &CGC, SRInfo *info)
00033 : CG(CGC.getCG()),
00034 CGC(CGC),
00035 CGT(CGC.getCGT()),
00036 CRT(CG.getRuntime()),
00037 SRI(info),
00038 Builder(CG.getLLVMContext()),
00039 SRF(0) { }
00040
00041 void CodeGenRoutine::emit()
00042 {
00043
00044
00045 if (SRI->isImported())
00046 return;
00047
00048
00049 std::auto_ptr<SRFrame> SRFHandle(new SRFrame(SRI, *this, Builder));
00050 SRF = SRFHandle.get();
00051 emitSubroutineBody();
00052 llvm::verifyFunction(*SRI->getLLVMFunction());
00053 }
00054
00055 void CodeGenRoutine::emitSubroutineBody()
00056 {
00057
00058 SubroutineDecl *SRDecl = SRI->getDeclaration();
00059 if (SRDecl->getDefiningDeclaration())
00060 SRDecl = SRDecl->getDefiningDeclaration();
00061
00062
00063
00064 BlockStmt *body = SRDecl->getBody();
00065 llvm::BasicBlock *bodyBB = emitBlockStmt(body, 0);
00066 if (!Builder.GetInsertBlock()->getTerminator())
00067 SRF->emitReturn();
00068
00069 SRF->emitPrologue(bodyBB);
00070 SRF->emitEpilogue();
00071 }
00072
00073 llvm::Function *CodeGenRoutine::getLLVMFunction() const
00074 {
00075 return SRI->getLLVMFunction();
00076 }
00077
00078 void CodeGenRoutine::emitObjectDecl(ObjectDecl *objDecl)
00079 {
00080 Type *objTy = resolveType(objDecl->getType());
00081
00082 if (objTy->isCompositeType()) {
00083 emitCompositeObjectDecl(objDecl);
00084 return;
00085 }
00086
00087 if (objTy->isFatAccessType()) {
00088
00089
00090
00091 if (objDecl->hasInitializer()) {
00092 CValue value = emitValue(objDecl->getInitializer());
00093 SRF->associate(objDecl, activation::Slot, value.first());
00094 return;
00095 }
00096
00097 const llvm::StructType *fatTy;
00098 const llvm::PointerType *dataTy;
00099 llvm::Value *slot;
00100 llvm::Value *ptr;
00101 llvm::Value *null;
00102
00103 fatTy = CGT.lowerFatAccessType(cast<AccessType>(objTy));
00104 dataTy = cast<llvm::PointerType>(fatTy->getElementType(0));
00105 slot = SRF->createEntry(objDecl, activation::Slot, fatTy);
00106 ptr = Builder.CreateStructGEP(slot, 0);
00107 null = llvm::ConstantPointerNull::get(dataTy);
00108 Builder.CreateStore(null, ptr);
00109 return;
00110 }
00111
00112
00113
00114 const llvm::Type *lowTy = CGT.lowerType(objTy);
00115 llvm::Value *slot = SRF->createEntry(objDecl, activation::Slot, lowTy);
00116 if (objDecl->hasInitializer()) {
00117 CValue value = emitValue(objDecl->getInitializer());
00118 Builder.CreateStore(value.first(), slot);
00119 }
00120 }
00121
00122 void CodeGenRoutine::emitRenamedObjectDecl(RenamedObjectDecl *objDecl)
00123 {
00124 Type *objTy = resolveType(objDecl->getType());
00125 Expr *objExpr = objDecl->getRenamedExpr()->ignoreInjPrj();
00126 llvm::Value *objValue;
00127
00128
00129
00130 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(objExpr)) {
00131
00132
00133 objValue = SRF->lookup(DRE->getDeclaration(), activation::Slot);
00134 }
00135 else if (objTy->isCompositeType())
00136 objValue = emitCompositeExpr(objExpr, 0, false).first();
00137 else
00138 objValue = emitReference(objExpr).first();
00139
00140 SRF->associate(objDecl, activation::Slot, objValue);
00141 }
00142
00143 CValue CodeGenRoutine::emitReference(Expr *expr)
00144 {
00145
00146 expr = expr->ignoreInjPrj();
00147
00148 CValue result;
00149
00150
00151 if (DeclRefExpr *refExpr = dyn_cast<DeclRefExpr>(expr)) {
00152 ValueDecl *decl = refExpr->getDeclaration();
00153 result = CValue::get(SRF->lookup(decl, activation::Slot));
00154 }
00155 else if (IndexedArrayExpr *idxExpr = dyn_cast<IndexedArrayExpr>(expr))
00156 result = emitIndexedArrayRef(idxExpr);
00157 else if (SelectedExpr *selExpr = dyn_cast<SelectedExpr>(expr))
00158 result = emitSelectedRef(selExpr);
00159 else if (DereferenceExpr *derefExpr = dyn_cast<DereferenceExpr>(expr)) {
00160
00161 result = emitValue(derefExpr->getPrefix());
00162 }
00163
00164 return result;
00165 }
00166
00167 CValue CodeGenRoutine::emitValue(Expr *expr)
00168 {
00169 switch (expr->getKind()) {
00170
00171 default:
00172 if (AttribExpr *attrib = dyn_cast<AttribExpr>(expr))
00173 return emitAttribExpr(attrib);
00174 else
00175 assert(false && "Cannot codegen expression!");
00176 break;
00177
00178 case Ast::AST_DeclRefExpr:
00179 return emitDeclRefExpr(cast<DeclRefExpr>(expr));
00180
00181 case Ast::AST_FunctionCallExpr:
00182 return emitFunctionCall(cast<FunctionCallExpr>(expr));
00183
00184 case Ast::AST_DereferenceExpr:
00185 return emitDereferencedValue(cast<DereferenceExpr>(expr));
00186
00187 case Ast::AST_InjExpr:
00188 return emitInjExpr(cast<InjExpr>(expr));
00189
00190 case Ast::AST_PrjExpr:
00191 return emitPrjExpr(cast<PrjExpr>(expr));
00192
00193 case Ast::AST_IntegerLiteral:
00194 return emitIntegerLiteral(cast<IntegerLiteral>(expr));
00195
00196 case Ast::AST_IndexedArrayExpr:
00197 return emitIndexedArrayValue(cast<IndexedArrayExpr>(expr));
00198
00199 case Ast::AST_SelectedExpr:
00200 return emitSelectedValue(cast<SelectedExpr>(expr));
00201
00202 case Ast::AST_ConversionExpr:
00203 return emitConversionValue(cast<ConversionExpr>(expr));
00204
00205 case Ast::AST_NullExpr:
00206 return emitNullExpr(cast<NullExpr>(expr));
00207
00208 case Ast::AST_QualifiedExpr:
00209 return emitValue(cast<QualifiedExpr>(expr)->getOperand());
00210
00211 case Ast::AST_AllocatorExpr:
00212 return emitAllocatorValue(cast<AllocatorExpr>(expr));
00213
00214 case Ast::AST_DiamondExpr:
00215 return emitDefaultValue(expr->getType());
00216 }
00217
00218 return CValue::get(0);
00219 }
00220
00221 void CodeGenRoutine::emitPragmaAssert(PragmaAssert *pragma)
00222 {
00223 CValue condition = emitValue(pragma->getCondition());
00224 const llvm::PointerType *messageTy = CG.getInt8PtrTy();
00225
00226
00227
00228 llvm::BasicBlock *assertBB = SRF->makeBasicBlock("assert-fail");
00229 llvm::BasicBlock *passBB = SRF->makeBasicBlock("assert-pass");
00230
00231
00232 Builder.CreateCondBr(condition.first(), passBB, assertBB);
00233
00234
00235
00236 Builder.SetInsertPoint(assertBB);
00237 llvm::Value *message;
00238 llvm::Value *messageLength;
00239
00240 if (pragma->hasMessage()) {
00241 BoundsEmitter emitter(*this);
00242 CValue msg = emitCompositeExpr(pragma->getMessage(), 0, true);
00243 message = msg.first();
00244 message = Builder.CreatePointerCast(message, messageTy);
00245 messageLength = emitter.computeTotalBoundLength(Builder, msg.second());
00246 }
00247 else {
00248 message = llvm::ConstantPointerNull::get(messageTy);
00249 messageLength = llvm::ConstantInt::get(CG.getInt32Ty(), 0);
00250 }
00251
00252 llvm::Value *fileName = CG.getModuleName();
00253 llvm::Value *lineNum = CG.getSourceLine(pragma->getLocation());
00254 CRT.raiseAssertionError(SRF, fileName, lineNum, message, messageLength);
00255
00256
00257 Builder.SetInsertPoint(passBB);
00258 }
00259
00260
00261 std::pair<llvm::Value*, llvm::Value*>
00262 CodeGenRoutine::emitRangeAttrib(RangeAttrib *attrib)
00263 {
00264 typedef std::pair<llvm::Value*, llvm::Value*> BoundPair;
00265 BoundsEmitter emitter(*this);
00266 BoundPair bounds;
00267
00268 if (ArrayRangeAttrib *arrayRange = dyn_cast<ArrayRangeAttrib>(attrib)) {
00269 CValue arrValue = emitArrayExpr(arrayRange->getPrefix(), 0, false);
00270 bounds = emitter.getBounds(Builder, arrValue.second(), 0);
00271 }
00272 else {
00273
00274
00275
00276 ScalarRangeAttrib *scalarRange = cast<ScalarRangeAttrib>(attrib);
00277 DiscreteType *scalarTy = scalarRange->getType();
00278 bounds = emitter.getScalarBounds(Builder, scalarTy);
00279 }
00280 return bounds;
00281 }
00282
00283 Type *CodeGenRoutine::resolveType(Type *type)
00284 {
00285 return const_cast<Type*>(CGT.resolveType(type));
00286 }