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 }