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  

callnode.cc

Go to the documentation of this file.
00001 // $Id: callnode.cc,v 1.5 2003/08/11 17:14:21 abrown 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 callNode::callNode(exprNode * name, expr_list * args, const Coord coord)
00045   : exprNode(Call, 0, coord),
00046     _name(name),
00047     _args(),
00048     _proc(0)
00049 {
00050   if (args) {
00051     _args.swap(* args);
00052     //delete args;
00053   }
00054 }
00055 
00056 // ------------------------------------------------------------
00057 // Data type base
00058 // ------------------------------------------------------------
00059 
00060 typeNode * callNode::base_type(bool TdefIndir) const
00061 {
00062   typeNode * calltype = name()->base_type(true);
00063 
00064   if (calltype->typ() == Ptr) {
00065     ptrNode * p = (ptrNode *) calltype;
00066     calltype = p->type();
00067     assert(p->typ() == Func);
00068   }
00069 
00070   return calltype->base_type(TdefIndir);
00071 }
00072 
00073 // ------------------------------------------------------------
00074 // Symbol lookup
00075 // ------------------------------------------------------------
00076 
00077 /*
00078 void callNode::lookup()
00079 {
00080   declNode * tmp;
00081 
00082   if (name()->typ() == Id) {
00083     idNode * id = (idNode *) name();
00084     declNode * var;
00085    
00086     var = CBZ::current_unit->ids()->lookup(id->name());
00087     if (! var) {
00088       var = CBZ::current_unit->externs()->lookup(id->name());
00089       if (! var) {
00090         CBZ::Warning(2, id->coord(),
00091                      string("implicitly declaring function to return int: ") +
00092                      id->name() + string("()."));
00093 
00094         var = new declNode(id->name().c_str(), declNode::EXTERN,
00095                            new funcNode(typeNode::NONE, (decl_list *)0,
00096                                         new primNode(id->coord()),
00097                                         id->coord()),
00098                            (exprNode *)0,
00099                            (exprNode *)0,
00100                            id->coord());
00101 
00102         var->decl_location(declNode::TOP);
00103         var->inc_references();
00104         id->decl(var);
00105 
00106         CBZ::current_unit->undef_funcs().push_back(var);
00107 
00108         tmp = CBZ::current_unit->ids()->insert(id->name(), var);
00109         tmp = CBZ::current_unit->externs()->insert(id->name(), var);
00110       }
00111       else { // only in Externals
00112 
00113         id->decl(var);
00114 
00115         // already referenced => no REFERENCE(var)
00116         // -- Ditto over here...
00117         // tmp = CBZ::current_unit->ids()->insert(id->text(), var);
00118       }
00119     }
00120     else {
00121       id->decl(var);
00122       var->inc_references();
00123 
00124       if (Symbols::TrackIds) {
00125         fprintf(stderr, "=== `%s' = ", id->name().c_str());
00126         // PrintNode(stderr, var, 0);
00127       }
00128     }
00129   }
00130   else
00131     name()->lookup();
00132 }
00133 */
00134 
00135 // ------------------------------------------------------------
00136 // Expression evaluator
00137 // ------------------------------------------------------------
00138 
00139 void callNode::eval()
00140 {
00141   // -- Evaluate all the arguments
00142 
00143   for (expr_list_p p = args().begin();
00144        p != args().end();
00145        ++p)
00146     {
00147       (*p)->eval();
00148     }
00149 
00150   // -- Cannot determine the value of a function
00151 
00152   value(constant());
00153 }
00154 
00155 // ------------------------------------------------------------
00156 //  Walker
00157 // ------------------------------------------------------------
00158 
00159 void callNode::visit(Visitor * the_visitor) 
00160 {
00161   the_visitor->at_call(this);
00162 }
00163 
00164 void callNode::walk(Walker & the_walker)
00165 {
00166   Walker::Order ord = the_walker.order(); 
00167 
00168   if (ord == Walker::Preorder || ord == Walker::Both)
00169     the_walker.at_call(this, Walker::Preorder);
00170 
00171   if (the_walker.depth() == Walker::Subtree) {
00172     // -- Visit the children 
00173 
00174     if (name())
00175       name()->walk(the_walker);
00176 
00177     list_walker(args(), the_walker);
00178 
00179     if (type())
00180       type()->walk(the_walker);
00181   }
00182 
00183   if (ord == Walker::Postorder || ord == Walker::Both)
00184     the_walker.at_call(this, Walker::Postorder);
00185 }
00186 
00187 // ------------------------------------------------------------
00188 //  Dataflow
00189 // ------------------------------------------------------------
00190 
00191 void callNode::dataflow(FlowVal * v, FlowProblem & fp)
00192 {
00193   if (fp.forward()) {
00194     fp.flow_call(v, this, FlowProblem::Entry);
00195 
00196     if (name())
00197       name()->dataflow(v, fp);
00198 
00199     dataflow_forward_list(args(), v, fp);
00200 
00201     fp.flow_call(v, this, FlowProblem::Exit);
00202   }
00203   else {
00204     fp.flow_call(v, this, FlowProblem::Exit);
00205 
00206     dataflow_reverse_list(args(), v, fp);
00207 
00208     if (name())
00209       name()->dataflow(v, fp);
00210 
00211     fp.flow_call(v, this, FlowProblem::Entry);
00212   }
00213 }
00214 
00215 // ------------------------------------------------------------
00216 // Output
00217 // ------------------------------------------------------------
00218 
00219 void callNode::output_expr(output_context & ct, Node * parent, int prec, Assoc assoc)
00220 {
00221   bool par = parens(prec, assoc);
00222   int myprec;
00223   Assoc myassoc;
00224 
00225   myprec = precedence(myassoc);
00226 
00227   if (par)
00228     ct << '(';
00229 
00230   name()->output_expr(ct, this, myprec, Left);
00231 
00232   ct << '(';
00233 
00234   output_delim_list(args(), ct, this, ',');
00235 
00236   ct << ')';
00237 
00238   if (par)
00239     ct << ')';
00240 }
00241 
00242 // ------------------------------------------------------------
00243 //  Changer
00244 // ------------------------------------------------------------
00245 
00246 Node * callNode::change(Changer & the_changer, bool redispatch)
00247 {
00248   Changer::Order ord = the_changer.order(); 
00249   callNode * the_call = this;
00250 
00251   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00252     the_call = (callNode *) the_changer.at_call(the_call, Changer::Preorder);
00253 
00254   if (the_call) {
00255 
00256     if (the_call != this)
00257       return the_call->change(the_changer, true);
00258 
00259     exprNode * old_name = the_call->name();
00260     if (old_name) {
00261       exprNode * new_name = (exprNode *) old_name->change(the_changer);
00262       if (old_name != new_name) {
00263         //if (the_changer.delete_old())
00264           //delete old_name;
00265         the_call->name(new_name);
00266       }
00267     }
00268 
00269     change_list(the_call->args(), the_changer);
00270 
00271     typeNode * old_type = the_call->type();
00272     if (old_type) {
00273       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00274       if (old_type != new_type) {
00275         //if (the_changer.delete_old())
00276           //delete old_type;
00277         the_call->type(new_type);
00278       }
00279     }
00280 
00281   }
00282 
00283   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00284     the_call = (callNode *) the_changer.at_call(the_call, Changer::Postorder);
00285 
00286   return the_call;
00287 }
00288 
00289 
00290 // ------------------------------------------------------------
00291 // Destructor
00292 // ------------------------------------------------------------
00293 
00294 callNode::~callNode()
00295 {
00296   //delete _name;
00297   //delete_list(_args);
00298 }

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