DefreprCheck.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 
00076 
00077 
00078 #include <stdint.h>
00079 #include <stdlib.h>
00080 #include <dirent.h>
00081 #include <fstream>
00082 #include <iostream>
00083 #include <string>
00084 #include <map>
00085 #include <sstream>
00086 #include <errno.h>
00087 #include "Version.hxx"
00088 #include "UocInfo.hxx"
00089 #include "AST.hxx"
00090 #include "Environment.hxx"
00091 #include "inter-pass.hxx"
00092 #include "backend.hxx"
00093 
00094 using namespace std;
00095 using namespace boost;
00096 using namespace sherpa;
00097 
00100 static shared_ptr<AST>
00101 getTypeAst(shared_ptr<AST> fld)
00102 {
00103   switch(fld->astType) {
00104   case at_field:
00105   case at_methdecl:
00106     return fld->child(1);
00107 
00108   case at_fill:
00109     return fld->child(0);
00110 
00111   default:
00112     assert(false);
00113     return GC_NULL;
00114   }
00115 }
00116 
00121 static size_t
00122 bitOffset(shared_ptr<AST> leg, size_t n)
00123 {
00124   size_t off = 0;
00125   for (size_t c=1; c < n; c++) {
00126     shared_ptr<AST> fld = leg->child(c);
00127     shared_ptr<AST> fldType = getTypeAst(fld);
00128     if (fldType->astType == at_bitfieldType)
00129       off += fldType->field_bits;
00130     else
00131       off += fldType->symType->size();
00132   }
00133 
00134   return off;
00135 }
00136 
00142 static bool
00143 TypesAgree(shared_ptr<AST> fld1, shared_ptr<AST> fld2)
00144 {
00145   shared_ptr<AST> fT1 = getTypeAst(fld1);
00146   shared_ptr<AST> fT2 = getTypeAst(fld2);
00147 
00148   if ((fT1->symType->strictlyEquals(fT2->symType)) &&
00149      (fT1->field_bits == fT2->field_bits))
00150     return true;
00151   else
00152     return false;
00153 }
00154 
00156 bool
00157 reprCheck(std::ostream& errStream, shared_ptr<AST> ast)
00158 {
00159   bool errFree = true;
00160   switch(ast->astType) {
00161   case at_defrepr:
00162   case at_declrepr:
00163   case at_reprctrs:
00164   case at_reprctr:
00165     assert(false);
00166     break;
00167 
00168   case at_defunion:
00169     {
00170       if ((ast->flags & UNION_IS_REPR) == 0)
00171         break;
00172 
00173       shared_ptr<AST> ctrs = ast->child(4);
00174 
00175       /* The fields in the when cluses must be of integer-type
00176          This may be relaxed later. */
00177       for (size_t c=0; c < ctrs->children.size(); c++) {
00178         shared_ptr<AST> ctrc = ctrs->child(c);
00179         
00180         for (size_t i=1; i < ctrc->children.size(); i++) {
00181           shared_ptr<AST> fldi = ctrc->child(i);
00182 
00183           if (fldi->astType == at_field)
00184             if (fldi->flags & FLD_IS_DISCM)
00185               if (!fldi->symType->isInteger()) {
00186                 errStream << fldi->loc << ": "
00187                           << " The discriminating field "
00188                           << fldi->child(0)->s
00189                           << " has a non-integer/bitfield type."
00190                           << std::endl;
00191                 errFree = false;
00192               }                  
00193         }
00194       }
00195 
00196       /* Ascertain that common fields are at the same bit-offset
00197          and have the same type */
00198       for (size_t c=0; c < ctrs->children.size(); c++) {
00199         shared_ptr<AST> ctrc = ctrs->child(c);
00200 
00201         for (size_t i=1; i < ctrc->children.size(); i++) {
00202           shared_ptr<AST> fldi = ctrc->child(i);
00203           if (fldi->astType != at_field)
00204             continue;
00205         
00206            size_t offc = bitOffset(ctrc, i);                  
00207           for (size_t d=c+1; d < ctrs->children.size(); d++) {
00208             shared_ptr<AST> ctrd = ctrs->child(d);
00209         
00210             for (size_t j=1; j < ctrd->children.size(); j++) {
00211               shared_ptr<AST> fldj = ctrd->child(j);
00212               if (fldj->astType != at_field)
00213                 continue;
00214         
00215               if (fldi->child(0)->s == fldj->child(0)->s) {
00216                 if (offc != bitOffset(ctrd, j)) {
00217                   errStream << ctrd->loc << ": "
00218                             << " The constructors "
00219                             << ctrc->child(0)->s << " and "
00220                             << ctrd->child(0)->s
00221                             << " don't agree on the bit-offset "
00222                             << " for field " << fldi->child(0)->s
00223                             << std::endl;
00224                   errFree = false;
00225                 }
00226                 
00227                 if (!TypesAgree(fldi, fldj)) {
00228                   errStream << ctrd->loc << ": "
00229                             << " The constructors "
00230                             << ctrc->child(0)->s << " and "
00231                             << ctrd->child(0)->s
00232                             << " don't agree on types "
00233                             << " for field " << fldi->child(0)->s
00234                             << std::endl;
00235                   errFree = false;
00236                 }
00237               }
00238             }
00239           }
00240         }
00241       }
00242 
00243       /* Ascertain that ``where'' fields are decisive */
00244       for (size_t c=0; c < ctrs->children.size(); c++) {
00245         shared_ptr<AST> ctrc = ctrs->child(c);
00246         
00247         typedef map<string, size_t> WhenMap;
00248         WhenMap when;
00249         
00250         for (size_t i=1; i < ctrc->children.size(); i++) {
00251           shared_ptr<AST> fldi = ctrc->child(i);
00252           if (fldi->flags & FLD_IS_DISCM) {
00253             assert(fldi->astType == at_field);
00254 
00255             when[fldi->child(0)->s] = fldi->unin_discm;
00256           }
00257         }
00258         
00259         for (size_t d=c+1; d < ctrs->children.size(); d++) {
00260           shared_ptr<AST> ctrd = ctrs->child(d);
00261           bool differ=false;
00262 
00263           for (size_t j=1; (!differ) && (j < ctrd->children.size()); j++) {
00264             shared_ptr<AST> fldj = ctrd->child(j);
00265 
00266             if (fldj->flags & FLD_IS_DISCM) {
00267               assert(fldj->astType == at_field);
00268         
00269               WhenMap::iterator itr_k = when.find(fldj->child(0)->s);
00270               if (itr_k == when.end())
00271                 continue;
00272 
00273               if (itr_k->second != fldj->unin_discm) {
00274                 differ=true;
00275                 break;
00276               }
00277             }
00278           }
00279         
00280           if (!differ) {
00281             errStream << ctrc->loc << ": "
00282                       << "Ambiguous defrepr constructors: "
00283                       << ctrc->child(0)->s << " and "
00284                       << ctrd->child(0)->s << ". Ambiguous case is: "
00285                       << std::endl;
00286         
00287             for (WhenMap::iterator itr_k = when.begin();
00288                 itr_k != when.end(); ++itr_k) {
00289               if (itr_k != when.begin())
00290                 errStream << ", ";        
00291               errStream << itr_k->first << " = " << itr_k->second;
00292             }
00293         
00294             errStream << "." << std::endl;        
00295             errFree = false;
00296           }
00297         }
00298       }
00299     }
00300 
00301   default:
00302     {
00303       // only defunion clause has meaning
00304       for (size_t c=0; c < ast->children.size(); c++)
00305         CHKERR(errFree, reprCheck(errStream, ast->child(c)));
00306       break;
00307     }
00308   }
00309 
00310   return errFree;
00311 }
00312 
00313 bool
00314 UocInfo::fe_reprCheck(std::ostream& errStream,
00315                       bool init, unsigned long flags)
00316 {
00317   bool errFree = reprCheck(errStream, uocAst);
00318   return errFree;
00319 }
00320 

Generated on Fri Feb 10 07:59:20 2012 for BitC Compiler by  doxygen 1.4.7