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  

unitnode.cc

Go to the documentation of this file.
00001 // $Id: unitnode.cc,v 1.8 2003/08/07 23:13:16 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 #include "goto_label_walker.h"
00040 #include "set_container_walker.h"
00041 #include "scope_walker.h"
00042 #include "id_lookup_walker.h"
00043 #include "enum_value_walker.h"
00044 
00045 #include <unistd.h>
00046 
00047 extern FILE * cbin;
00048 extern int cbparse();
00049 
00050 // --------------------------------------------------------------------
00051 // Constructors
00052 // --------------------------------------------------------------------
00053 
00054 unitNode::unitNode(string input_file, string output_file,
00055                    const Coord coord)
00056   : Node(Unit, coord),
00057     _defs(),
00058     _symbol_level(0),
00059     _types(new Identifiers_table()),
00060     _tags(new Tags_table()),
00061     _input_file(input_file),
00062     _output_file(output_file),
00063     _errors(0),
00064     _warnings(0),
00065     _undef_funcs(),
00066     _suespecs() { }
00067 
00068 // ------------------------------------------------------------
00069 // Parse
00070 // ------------------------------------------------------------
00071 
00072 void unitNode::parse(str_list * cpp_flags, bool abortOnError)
00073 {
00074   // -- Open the input file
00075 
00076   if (_input_file == "(stdin)")
00077     cbin = stdin;
00078   else {
00079     cbin = _open_input_file(cpp_flags);
00080   }
00081     
00082   // -- Add the filename to the compilation list (init CBZ::Files)
00083   
00084   CBZ::set_file(_input_file.c_str(), 0, true);  
00085 
00086   // -- Make this the current unit...
00087 
00088   CBZ::current_unit = this;
00089   
00090   // -- Run the parser
00091 
00092   int parse_ok = cbparse();
00093 
00094   if (CBZ::Preprocess && (cbin != stdin))
00095 #if !defined(_WIN32)
00096     pclose(cbin);
00097 #else
00098     _pclose(cbin);
00099 #endif
00100   
00101   // -- Abort on any errors
00102 
00103   if (CBZ::current_unit->errors() && abortOnError) {
00104         abort();
00105   }
00106 
00107   // -- Perform "fixups"
00108 
00109   fixup();
00110 }
00111 
00112 // -- Utility: open the file and run the preprocessor...
00113 
00114 FILE * unitNode::_open_input_file(str_list * cpp_flags)
00115 {
00116   FILE * in_file = 0;
00117   bool std_in;
00118 
00119   std_in = (_input_file == "(stdin)");
00120   if (! std_in &&
00121       (access(_input_file.c_str(), F_OK) != 0) &&
00122       (access(_input_file.c_str(), R_OK) != 0)) {
00123     cerr << "Unable to open input file " << _input_file << endl;
00124     exit(1);
00125   }
00126 
00127   if (CBZ::Preprocess && ! std_in) {  
00128     string command = CBZ::preproc;
00129     for (str_list_p p = cpp_flags->begin();
00130          p != cpp_flags->end();
00131          ++p)
00132       command += " " + (*p);
00133     command += " " + _input_file;
00134 
00135     if (CBZ::ShowPreprocess)
00136       cout << "Preprocess: " << command << endl;
00137       
00138 #if !defined(_WIN32)
00139     in_file = popen(command.c_str(), "r");
00140 #else
00141     in_file = _popen(command.c_str(), "r");
00142 #endif  /*      !defined(_WIN32)        */    
00143 
00144     if (! in_file) {
00145       cerr << "Unable to preprocess input file " << _input_file << endl;
00146       cerr << "Command: " << command << endl;
00147       exit(1);
00148     }
00149   }
00150   else {
00151     if (! std_in) {
00152       in_file = fopen(_input_file.c_str(), "r");
00153 
00154       if (! in_file) {
00155         cerr << "Unable to open input file " << _input_file << endl;
00156         exit(1);
00157       }
00158     }
00159     else
00160       in_file = stdin;
00161   }
00162 
00163   return in_file;
00164 }
00165 
00166 void unitNode::fixup()
00167 {
00168   // -- Perform "fixups"
00169 
00170   set_container_walker::fixup(this);
00171   goto_label_walker::fixup(this);
00172   id_lookup_walker::fixup(this, true);
00173   enum_value_walker::assign(this);
00174 }
00175   
00176 // ------------------------------------------------------------
00177 // Symbol tables
00178 // ------------------------------------------------------------
00179 
00180 void unitNode::enter_scope()
00181 {
00182   types()->enter_scope();
00183   tags()->enter_scope();
00184 
00185   ++_symbol_level;
00186 }
00187 
00188 void unitNode::exit_scope()
00189 {
00190   if (_symbol_level == 0)
00191     CBZ::SyntaxError(string("missing '{' detected"));
00192   else {
00193     types()->exit_scope();
00194     tags()->exit_scope();
00195 
00196     --_symbol_level;
00197   }
00198 }
00199 
00200 // ------------------------------------------------------------
00201 //  Walker
00202 // ------------------------------------------------------------
00203 
00204 void unitNode::visit(Visitor * the_visitor) 
00205 {
00206   the_visitor->at_unit(this);
00207 }
00208 
00209 void unitNode::walk(Walker & the_walker)
00210 {
00211   Walker::Order ord = the_walker.order(); 
00212 
00213   if (ord == Walker::Preorder || ord == Walker::Both)
00214     the_walker.at_unit(this, Walker::Preorder);
00215 
00216   if (the_walker.depth() == Walker::Subtree) {
00217     // -- Visit the children 
00218 
00219     list_walker(undef_funcs(), the_walker);
00220     list_walker(suespecs(), the_walker);
00221     list_walker(defs(), the_walker);
00222   }
00223 
00224   if (ord == Walker::Postorder || ord == Walker::Both)
00225     the_walker.at_unit(this, Walker::Postorder);
00226 }
00227 
00228 // ------------------------------------------------------------
00229 //  Dataflow
00230 // ------------------------------------------------------------
00231 
00232 void unitNode::dataflow(FlowVal * v, FlowProblem & fp)
00233 {
00234   if (fp.forward()) {
00235     fp.flow_unit(v, this, FlowProblem::Entry);
00236     fp.flow_unit(v, this, FlowProblem::Exit);
00237   }
00238   else {
00239     fp.flow_unit(v, this, FlowProblem::Exit);
00240     fp.flow_unit(v, this, FlowProblem::Entry);
00241   }
00242 }
00243 
00244 // ------------------------------------------------------------
00245 // Ouput
00246 // ------------------------------------------------------------
00247 
00248 void unitNode::output(output_context & ct, Node * parent)
00249 {
00250   def_list & ds = defs();
00251 
00252   _symbol_level = 0;
00253   for (def_list_p p = ds.begin();
00254        p != ds.end();
00255        ++p)
00256     {
00257       // -- Don't output code from included files...
00258 
00259       int fnum = (*p)->coord().file();
00260       bool included = false;
00261 
00262       if (fnum >= 0) {
00263         string & cur_name = CBZ::Files[fnum];
00264         included = (cur_name != _input_file);
00265       }
00266 
00267       if (! included) {
00268         ct << '\n';
00269         (*p)->output(ct, parent);
00270       }
00271     }
00272 }
00273 
00274 
00275 // ------------------------------------------------------------
00276 //  Changer
00277 // ------------------------------------------------------------
00278 
00279 Node * unitNode::change(Changer & the_changer, bool redispatch)
00280 {
00281   Changer::Order ord = the_changer.order(); 
00282   unitNode * the_unit = this;
00283 
00284   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00285     the_unit = (unitNode *) the_changer.at_unit(the_unit, Changer::Preorder);
00286 
00287   if (the_unit) {
00288 
00289     if (the_unit != this)
00290       return the_unit->change(the_changer, true);
00291 
00292     change_list(the_unit->suespecs(), the_changer);
00293     change_list(the_unit->undef_funcs(), the_changer);
00294     change_list(the_unit->defs(), the_changer);
00295   }
00296 
00297   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00298     the_unit = (unitNode *) the_changer.at_unit(the_unit, Changer::Postorder);
00299 
00300   return the_unit;
00301 }
00302 
00303 
00304 // ------------------------------------------------------------
00305 // Destructor
00306 // ------------------------------------------------------------
00307 
00308 unitNode::~unitNode()
00309 {
00310   //delete_list(_defs);
00311   //delete_list(_undef_funcs);
00312   //delete_list(_suespecs);
00313   // What about symbol tables?
00314 }

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