Type-size.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright (C) 2008, Johns Hopkins University.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or
00007  * without modification, are permitted provided that the following
00008  * conditions are met:
00009  *
00010  *   - Redistributions of source code must contain the above 
00011  *     copyright notice, this list of conditions, and the following
00012  *     disclaimer. 
00013  *
00014  *   - Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions, and the following
00016  *     disclaimer in the documentation and/or other materials 
00017  *     provided with the distribution.
00018  *
00019  *   - Neither the names of the copyright holders nor the names of any
00020  *     of any contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written
00022  *     permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  **************************************************************************/
00037 
00038 #include <assert.h>
00039 #include <stdint.h>
00040 #include <stdlib.h>
00041 #include <dirent.h>
00042 #include <fstream>
00043 #include <iostream>
00044 #include <string>
00045 #include <sstream>
00046 
00047 #include <libsherpa/UExcept.hxx>
00048 
00049 #include "AST.hxx"
00050 #include "Type.hxx"
00051 #include "machine-dep.hxx"
00052 
00053 using namespace boost;
00054 using namespace sherpa;
00055 
00056 static size_t
00057 calc_struct_size(const shared_ptr<Type> t)
00058 {
00059   size_t start=0;
00060   size_t sz = 0;
00061   shared_ptr<AST> base = GC_NULL;
00062 
00063   if (t->typeTag == ty_structv) {
00064     start = 0;
00065     base = t->defAst->defForm->child(4);
00066   }
00067   else if (t->typeTag == ty_uconv) {
00068     start = 1;
00069     base = t->defAst;
00070   }
00071   else
00072     assert(false);
00073   
00074 
00075   // Fill elements and repr discriminators are not a part of the type.
00076   // So, we need a separate count for the type components.
00077   size_t compCnt=0;
00078   for (size_t i=start; i < base->children.size(); i++) {
00079     shared_ptr<AST> fld = base->child(i);
00080     
00081     switch(fld->astType) {
00082     case at_fill:
00083       {
00084         sz += fld->field_bits;
00085         break;
00086       }
00087       
00088     case at_field:
00089       {
00090         if (fld->field_bits != 0) {
00091           assert(fld->symType->isIntegral());
00092           sz += fld->field_bits;
00093         }
00094         else {
00095           sz+= t->CompType(compCnt)->size();
00096         }
00097 
00098         if ((fld->flags & FLD_IS_DISCM) == 0)
00099           compCnt++;
00100         break;
00101       }
00102       
00103     case at_methdecl:
00104       // Legal, but no bits contributed.
00105       break;
00106 
00107     default:
00108       {
00109         assert(false);
00110         break;
00111       }
00112     }
00113   }
00114     
00115   return sz;
00116 }
00117 
00118 
00119 static size_t
00120 calc_unin_size(const shared_ptr<Type> t)
00121 {
00122   assert(t->typeTag == ty_unionv);
00123   shared_ptr<AST> base = t->defAst->defForm;
00124   
00125   size_t max=0;
00126   for (size_t i=0; i < base->children.size(); i++) {
00127     shared_ptr<AST> ctr = base->child(i);
00128 
00129     // Constructors like `nil' having no arguments do not count.
00130     if (ctr->symType->isUval())
00131       continue;
00132     
00133     assert(ctr->symType->isUcon());
00134     size_t sz = calc_struct_size(ctr->symType);
00135     
00136     if (max < sz)
00137       max = sz;
00138   }
00139    
00140   size_t tag=0;
00141   if ((base->flags & ENUM_UN) || (base->flags & SINGLE_LEG_UN) || 
00142      (base->flags & CARDELLI_UN) || (base->flags & UNION_IS_REPR))
00143     tag=0;
00144   else 
00145     tag = base->tagType->size();
00146 
00147   return (max + tag);
00148 }
00149 
00150 
00151 size_t
00152 Type::size() 
00153 { 
00154   if (getType() != shared_from_this())
00155     return link->getType()->size();
00156 
00157   if (mark & MARK_SIZE)
00158     assert(false);
00159 
00160   mark |= MARK_SIZE;
00161 
00162   size_t theSize=0;
00163   
00164   switch(typeTag) {
00165   case ty_unit:
00166   case ty_bool:
00167   case ty_char:
00168     theSize = 8;
00169     break;
00170 
00171   case ty_int8:
00172   case ty_uint8:
00173   case ty_int16:
00174   case ty_uint16:
00175   case ty_int32:
00176   case ty_uint32:
00177   case ty_int64:
00178   case ty_uint64:
00179     theSize = nBits();
00180     break;
00181 
00182   case ty_word:
00183     theSize = TARGET_WORD_SIZE;
00184     break;
00185 
00186   case ty_float:
00187     theSize = TARGET_FLOAT_SIZE;
00188     break;
00189 
00190   case ty_double:
00191     theSize = TARGET_DOUBLE_SIZE;
00192     break;
00193 
00194   case ty_quad:
00195     theSize = TARGET_QUAD_SIZE;
00196     break;
00197     
00198 #ifdef KEEP_BF
00199   case  ty_bitfield:
00200     theSize = Isize;
00201     break;
00202 #endif
00203 
00204   case ty_fn:
00205   case ty_method:
00206   case ty_string:
00207   case ty_dummy:
00208   case ty_structr:
00209   case ty_unionr:
00210   case ty_uvalr:
00211   case ty_uconr:
00212   case ty_vector:
00213   case ty_ref:
00214   case ty_byref:
00215   case ty_exn:
00216     theSize = TARGET_WORD_SIZE;
00217     break;
00218 
00219   case ty_array_ref:
00220     theSize = TARGET_WORD_SIZE * 2;
00221     break;
00222 
00223   case ty_tvar:
00224   case ty_fnarg:
00225   case ty_tyfn:
00226   case ty_letGather:
00227   case ty_typeclass:    
00228   case ty_pcst:
00229   case ty_kvar:
00230   case ty_kfix:
00231   case ty_field:
00232     assert(false);
00233     break;
00234     
00235   case ty_structv:
00236     {
00237       //       // Fix: inner bit-fields
00238       //       for (size_t i=0; i < components->size(); i++)
00239       //         theSize += CompType(i)->size();
00240       //       theSize += defAst->total_fill;
00241       //       break;
00242       
00243       theSize = calc_struct_size(shared_from_this());
00244       break;
00245     }
00246 
00247   case ty_unionv: 
00248     {
00249       theSize = calc_unin_size(shared_from_this());
00250       break;
00251     }
00252 
00253   case ty_uvalv: 
00254   case ty_uconv: 
00255     {
00256       theSize = getUnionType()->size();
00257       break;
00258     }
00259     
00260   case ty_array:
00261     {
00262       theSize = Base()->size() * arrLen->len;
00263       break;
00264     }
00265     
00266   case ty_mbTop:
00267   case ty_mbFull:
00268     {
00269       theSize = Core()->size();
00270     }
00271     
00272   case ty_mutable:
00273   case ty_const:
00274     {
00275       theSize = Base()->size();      
00276       break;
00277     }
00278   }
00279   
00280   mark &= ~MARK_SIZE;
00281   return theSize;
00282 }
00283 

Generated on Thu May 17 23:59:16 2012 for BitC Compiler by  doxygen 1.4.7