C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

suespecnode.cc

Go to the documentation of this file.
00001 // $Id: suespecnode.cc,v 1.7 2003/08/07 23:13:13 pnav Exp $
00002 // ----------------------------------------------------------------------
00003 //
00004 //  C-Breeze
00005 //  C Compiler Framework
00006 // 
00007 //  Copyright (c) 2000 University of Texas at Austin
00008 // 
00009 //  Samuel Z. Guyer
00010 //  Daniel A. Jimenez
00011 //  Calvin Lin
00012 // 
00013 //  Permission is hereby granted, free of charge, to any person
00014 //  obtaining a copy of this software and associated documentation
00015 //  files (the "Software"), to deal in the Software without
00016 //  restriction, including without limitation the rights to use, copy,
00017 //  modify, merge, publish, distribute, sublicense, and/or sell copies
00018 //  of the Software, and to permit persons to whom the Software is
00019 //  furnished to do so, subject to the following conditions:
00020 //  
00021 //  The above copyright notice and this permission notice shall be
00022 //  included in all copies or substantial portions of the Software.
00023 //  
00024 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00028 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00029 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00030 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00031 //  THE SOFTWARE.
00032 //
00033 //  We acknowledge the C-to-C Translator from MIT Laboratory for
00034 //  Computer Science for inspiring parts of the C-Breeze design.
00035 //
00036 // ----------------------------------------------------------------------
00037 
00038 #include "c_breeze.h"
00039 
00040 // --------------------------------------------------------------------
00041 // Constructors
00042 // --------------------------------------------------------------------
00043 
00044 suespecNode::suespecNode(const char * name, decl_list * fields,
00045                          NodeType owner,
00046                          unitNode * u,
00047                          const Coord coord)
00048   : typeNode(sueSpec, NONE, 0, coord),
00049     _name(string(name)),
00050     _fields(),
00051     _complete(false),
00052     _visited(false),
00053     _size(0),
00054     _align(1),
00055     _owner(owner),
00056     _scope_output(0)
00057 {
00058   if (fields) {
00059     _fields.swap(*fields);
00060     _complete = true;
00061     //delete fields;
00062   }
00063   // -- Keep all suespecNodes in a global list, since none of
00064   // the struct/union/enum nodes actually "own" them.
00065 
00066   u->suespecs().push_back(this);
00067 }
00068 
00069 // --------------------------------------------------------------------
00070 // Tag operations
00071 // --------------------------------------------------------------------
00072 
00073 bool suespecNode::same_tag_as(suespecNode * other)
00074 {
00075   if (name().empty() || other->name().empty())
00076     return false;
00077   else
00078     return name() == other->name();
00079 }
00080 
00081 // --- tag_conflict from sue.c
00082 // What this function does now is update the suespecNode whenever a new
00083 // sue-specifier is encountered.
00084 
00085 void suespecNode::update(decl_list * fields, sueNode * sue, const Coord right)
00086 {
00087   if (sue->typ() != owner()) {
00088     CBZ::SyntaxError(sue->coord(),
00089                      string("redeclaration of structure/union/enum tag `") +
00090                      name() + string("'"));
00091     cerr << "\tPrevious declaration: " << coord() << endl;
00092 
00093     return;
00094   }
00095 
00096   if (fields)
00097     if (complete()) {
00098 
00099       // -- Error: fields already specified...
00100 
00101       string tp;
00102       switch (sue->typ()) {
00103       case Struct:
00104         tp = string("structure");
00105         break;
00106       case Union:
00107         tp = string("union");
00108         break;
00109       case Enum:
00110         tp = string("enum");
00111         break;
00112       default:
00113         break;
00114       }
00115 
00116       CBZ::SyntaxError(sue->coord(),
00117                        string("multiple declarations of ") +
00118                        tp + string(" `") +
00119                        name() + string("'"));
00120       cerr << "\tPrevious definition: " << coord() << endl;
00121     }
00122     else {
00123 
00124       // -- Update the suespec with the fields...
00125 
00126       _fields.swap(*fields);
00127       //delete fields;
00128       complete(true);
00129       coord(right);
00130     }
00131 }
00132 
00142 declNode * suespecNode::find_field(const string & name)
00143 {
00144   for (decl_list_p p = fields().begin();
00145        p != fields().end();
00146        ++p)
00147     {
00148       if ((*p)->name() == name)
00149         return (*p);
00150     }
00151 
00152   return 0;
00153 }
00154 
00155 
00156 // ------------------------------------------------------------
00157 //  Walker
00158 // ------------------------------------------------------------
00159 
00160 void suespecNode::visit(Visitor * the_visitor) 
00161 {
00162   the_visitor->at_suespec(this);
00163 }
00164 
00165 void suespecNode::walk(Walker & the_walker)
00166 {
00167   Walker::Order ord = the_walker.order(); 
00168 
00169   if (ord == Walker::Preorder || ord == Walker::Both)
00170     the_walker.at_suespec(this, Walker::Preorder);
00171 
00172   if (the_walker.depth() == Walker::Subtree) {
00173     // -- Visit the children 
00174 
00175     list_walker(fields(), the_walker);
00176   }
00177 
00178   if (ord == Walker::Postorder || ord == Walker::Both)
00179     the_walker.at_suespec(this, Walker::Postorder);
00180 }
00181 
00182 // ------------------------------------------------------------
00183 // Output
00184 // ------------------------------------------------------------
00185 
00186 void suespecNode::output_type(output_context & ct, Node * parent, Assoc context, Type_qualifiers q)
00187 {
00188   if (owner() == Enum) {
00189     ct.space();
00190     if (!ct.isPrinted(this)) {
00191         ct << '{';
00192         ct.space();
00193         output_delim_list(fields(), ct, this, ',');
00194         ct.space();
00195         ct << '}';
00196         ct.printed(this);
00197         scope_output(CBZ::current_unit->symbol_level());
00198     }
00199   }
00200   else {
00201     // djimenez
00202     // if this body has already been output, don't output
00203     // it again; many compilers will reject an identical definition
00204     // as a redefinition
00205 
00206     if (!ct.isPrinted(this)) {
00207         ct.new_line();
00208         ct << '{';
00209         ct.indent_in();
00210         output_list(fields(), ct, this);
00211         ct.indent_out();
00212         ct.new_line();
00213         ct << '}';
00214         ct.printed(this);
00215         scope_output(CBZ::current_unit->symbol_level());
00216     }
00217   }
00218 }
00219 
00220 // ------------------------------------------------------------
00221 //  Changer
00222 // ------------------------------------------------------------
00223 
00224 Node * suespecNode::change(Changer & the_changer, bool redispatch)
00225 {
00226   Changer::Order ord = the_changer.order(); 
00227   suespecNode * the_suespec = this;
00228 
00229   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00230     the_suespec = (suespecNode *) the_changer.at_suespec(the_suespec, Changer::Preorder);
00231 
00232   if (the_suespec) {
00233 
00234     if (the_suespec != this)
00235       return the_suespec->change(the_changer, true);
00236 
00237     change_list(the_suespec->fields(), the_changer);
00238 
00239   }
00240 
00241   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00242     the_suespec = (suespecNode *) the_changer.at_suespec(the_suespec, Changer::Postorder);
00243 
00244   return the_suespec;
00245 }
00246 
00247 
00248 // ------------------------------------------------------------
00249 // Destructor
00250 // ------------------------------------------------------------
00251 
00252 suespecNode::~suespecNode()
00253 {
00254   //delete_list(_fields);
00255 }

Generated on August 27, 2003
Back to the C-Breeze home page