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  

declnode.cc

Go to the documentation of this file.
00001 // $Id: declnode.cc,v 1.11 2003/08/11 17:15:59 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 #include "ref_clone_changer.h"
00040 
00041 // --------------------------------------------------------------------
00042 // Constructors
00043 // --------------------------------------------------------------------
00044 
00045 declNode::declNode(const char * name, Storage_class sc, typeNode * the_type,
00046                    exprNode * init, exprNode * bitsize,
00047                    const Coord coord)
00048   : defNode(Decl, coord),
00049     _type(the_type),
00050     _name(string(name)),
00051     _decl_location(UNKNOWN),
00052     _storage_class(sc),
00053     _is_redundant_extern(false),
00054     _init(init), 
00055     _bitsize(bitsize),
00056     _references(0),
00057     _ref_list(),
00058     _attribs()
00059 {}
00060 
00061 // -- Was ConvertIdToDecl
00062 
00063 declNode::declNode(idNode * id, Storage_class sc, typeNode * the_type,
00064                    exprNode * init, exprNode * bitsize)
00065   : defNode(Decl, id->coord()),
00066     _type(the_type),
00067     _name(id->name()),
00068     _decl_location(UNKNOWN),
00069     _storage_class(sc),
00070     _is_redundant_extern(false),
00071     _init(init), 
00072     _bitsize(bitsize),
00073     _references(0),
00074     _ref_list(),
00075     _attribs()
00076 {
00077   //delete id;
00078 }
00079 
00080 // --- BuildEnumConst from sue.c
00081 
00082 declNode::declNode(idNode * idname, exprNode * value)
00083   : defNode(Decl, idname->coord()),
00084     _type(0),
00085     _name(idname->name()),
00086     _decl_location(ENUM),
00087     _storage_class(NONE),
00088     _is_redundant_extern(false),
00089     _init(value),
00090     _bitsize(0),
00091     _references(0),
00092     _ref_list(),
00093     _attribs()
00094 {
00095   primNode * tp = new primNode(typeNode::CONST);
00096   type(tp);
00097 
00098   /*
00099   orig = CBZ::current_unit->ids()->insert(name(), this);
00100   if (orig) {
00101     CBZ::SyntaxError(coord(),
00102                      string("enum constant `") + 
00103                      orig->name() + 
00104                      string("' redeclares previous identifier"));
00105     cerr << "\tPrevious definition: " << orig->coord() << endl;
00106   }
00107   */
00108 
00109   //delete idname;
00110 }
00111 
00112 // ------------------------------------------------------------
00113 // Make an abstract declarator into a  declaration
00114 // ------------------------------------------------------------
00115 
00116 declNode::declNode(typeNode * the_type, Storage_class sc = NONE)
00117   : defNode(Decl, the_type->coord()),
00118     _type(the_type),
00119     _name(string("")),
00120     _decl_location(UNKNOWN),
00121     _storage_class(sc),
00122     _is_redundant_extern(false),
00123     _init(0),
00124     _bitsize(0),
00125     _references(0),
00126     _ref_list(),
00127    _attribs()
00128 {
00129   if (CBZ::OldStyleFunctionDefinition) {
00130     cout << "declNode::declNode \"" << _name << "\"" << endl;
00131   }
00132 }
00133 
00134 // ------------------------------------------------------------
00135 // ModifyType in complex-types.c
00136 // ------------------------------------------------------------
00137 
00138 void declNode::modify_type(typeNode * the_type)
00139 {
00140   if ( ! type())
00141     type(the_type);
00142   else
00143     type()->set_base_type(the_type);
00144 }
00145 
00146 declNode * declNode::modify_type_and(typeNode * the_type)
00147 {
00148   modify_type(the_type);
00149   return this;
00150 }
00151 
00152 declNode * declNode::modify_type_and(declNode * the_decl)
00153 {
00154   modify_type(the_decl->type());
00155   the_decl->type((typeNode *)0);
00156   //delete the_decl;
00157   return this;
00158 }
00159 
00160 // ------------------------------------------------------------
00161 // FinishDecl from complex-types.c
00162 // ------------------------------------------------------------
00163 
00164 // We store the storage class for a declaration in a global variable
00165 // (declNode::CUR_SC) and then retrieve it in finish().
00166 
00167 //   WARNING:  FinishDecl may be run more than once on a decl, so it
00168 //   should not blindly make unnecessary changes.
00169 
00170 void declNode::finish(Storage_class sc)
00171 {
00172   typeNode * the_type = type();
00173 
00174   the_type->finish();
00175 
00176   // -- Retrieve the storage class populated during parsing
00177 
00178   storage_class(sc);
00179 
00180   // -- check for incomplete struct/union/enum
00181 
00182   if (the_type && (storage_class() != TYPEDEF))
00183     the_type->verify_sue_complete();
00184 }
00185 
00186 declNode * declNode::finish_and(Storage_class sc)
00187 {
00188   finish(sc);
00189   return this;
00190 }
00191 
00192 // ------------------------------------------------------------
00193 // SetDeclType in complex-types.c
00194 // Sets the type part of a declaration
00195 // ------------------------------------------------------------
00196 
00197 void declNode::set_type(typeNode * the_type, Storage_class sc, ScopeState redeclare)
00198 {
00199   declNode * orig; // -- For symbol table lookups
00200 
00201   // -- Set the type or base-type..
00202 
00203   modify_type(the_type);
00204 
00205   // djimenez
00206 
00207   storage_class(sc);
00208 
00209   if (the_type->is_derived()) {
00210 
00211     // these three will call SetDeclType again when
00212     // their base type is set
00213 
00214     return;
00215   }
00216 
00217   //*******************************************************
00218   //
00219   // Hereafter we finish up the decl, cleaning it up, moving
00220   // storage classes to Decl node, and inserting it in the
00221   // symbol table.
00222 
00223   // This part is largely duplicated in the id_lookup_walker
00224   // so, maybe I should chop this down.
00225   // SZG
00226   //********************************************************
00227 
00228   finish(sc);
00229 
00230   // -- This is the only symbol table maintenance that is done during
00231   // parsing. It is required to distinguish identifier names from type
00232   // names (the only context sensitive aspect of C).
00233 
00234   // pnav
00235   // commenting out the guard should fix typedef-ident clashes
00236   if (storage_class() == TYPEDEF)
00237     orig = CBZ::current_unit->types()->insert(name(), this);
00238 
00239   /*
00240   if (CBZ::OldStyleFunctionDefinition)
00241     // this declaration is part of an old-style function definition,
00242     // so treat it as a formal parameter
00243     if (redeclare != SU)
00244       redeclare = Formal;
00245 
00246   if (storage_class() == TYPEDEF)
00247     var = this;
00248   else 
00249     if (type()->typ() == Func && (redeclare != Formal)) {
00250 
00251       // the formal parameter line was added by Manish 2/2/94  this fixes bugs
00252       //   like :  
00253       //          int a(int f(int,int))
00254       //          {}
00255       //          
00256       //          int b(int f(double,float)) 
00257       //          {} 
00258 
00259       // if the arglist contains Id's, then we are in the middle of
00260       //   an old-style function definition, so don't insert the symbol.
00261       //   It will be inserted by DefineProc
00262 
00263       funcNode * the_func = (funcNode *) type();
00264       decl_list & the_args = the_func->args();
00265 
00266       if (! the_args.empty())
00267         if (the_args.front()->typ() == Id)
00268           return;
00269 
00270       // -- normal function declaration, check for consistency with Externals
00271 
00272       var = this;
00273       orig = CBZ::current_unit->externs()->insert(var->name(), var);
00274       if (orig) {
00275         // -- FunctionConflict from procedure.c
00276         funcNode * ofunc = (funcNode *) orig->type();
00277 
00278         // -- If the old definition is not compatible...
00279         if (! ofunc->is_compatible_with(the_func)) {
00280           // CBZ::SyntaxError(the_func->coord(),
00281           //               string("function identifier `") + name() +
00282           //               string("' redeclared"));
00283           // cerr << "\tPrevious declaration: " << orig->coord() << endl;
00284         }
00285 
00286         var = orig;
00287       }
00288 
00289     } else
00290       if ((storage_class() == EXTERN) ||
00291           (CBZ::current_unit->symbol_level() == 0  &&  redeclare == Redecl)) {
00292 
00293         // -- top-level variable, check for consistency with Externals
00294         var = this;
00295         orig = CBZ::current_unit->externs()->insert(var->name(), var);
00296         if (orig) {
00297           // "external declarations for the same identifier must agree in
00298           // type and linkage" --  K&R2, A10.2
00299           if (! (* orig->type() == * var->type()) ) {
00300             // CBZ::SyntaxError(var->coord(),
00301             //       string("extern `") + orig->name() + 
00302             //       string("' redeclared"));
00303             // cerr << "\tPrevious declaration: " << orig->coord() << endl;
00304 
00305             // orig->type(var->type());
00306             // orig->coord(var->coord());
00307           }
00308           var = orig;
00309         }
00310 
00311       } else
00312         var = this;
00313 
00314   // Check if decl is a redundant external declaration.  (See
00315   // description of T_REDUNDANT_EXTERNAL_DECL in ast.h.)
00316 
00317   if (var != this) {
00318     // Name was already in Externals symbol table, so possibly redundant.
00319     // Look for previous declaration in scope
00320 
00321     orig = CBZ::current_unit->ids()->lookup(name());
00322     if (orig)
00323       set_redundant_extern(true);
00324   }
00325 
00326   switch (redeclare) {
00327   case NoRedecl:
00328     if (CBZ::current_unit->ids()->is_a_type(name()))
00329       CBZ::SyntaxError(coord(),
00330                        string("illegal to redeclare typedef `") + 
00331                        name() + string("' with default type"));
00332 
00333     // -- falls through to Redecl
00334   case Redecl:
00335     if (CBZ::current_unit->symbol_level() == 0)
00336       decl_location(TOP);
00337     else
00338       decl_location(BLOCK);
00339 
00340     // -- add to current scope
00341     orig = CBZ::current_unit->ids()->insert(name(), var);
00342     if ((orig) && (orig != var)) {
00343       // -- The two are equal for redundant function/extern declarations
00344       // CBZ::SyntaxError(var->coord(),
00345       //               string("variable `") + orig->name() +
00346       //               string("' redeclared"));
00347       // cerr << "\tPrevious declaration: " << orig->coord() << endl;
00348     }
00349 
00350     break;
00351 
00352   case SU:
00353     decl_location(SU);
00354 
00355     // each struct/union has it own namespace for fields
00356     break;
00357 
00358   case Formal:
00359     decl_location(FORMAL);
00360 
00361     if ((storage_class() != NONE) &&
00362         (storage_class() != REGISTER)) {
00363       CBZ::SyntaxError(coord(),
00364                        string("illegal storage class for parameter `") + 
00365                        name() + string("'"));
00366 
00367       if (storage_class() == TYPEDEF)
00368         break;
00369 
00370       // reset storage class for body
00371       //storage_class(NONE);
00372       // why? djimenez
00373     }
00374 
00375     // convert Array to pointer
00376       
00377     if (type()->typ() == Array) {
00378       arrayNode * atype = (arrayNode *) get_type();
00379       type(new ptrNode(atype->type_qualifiers(),
00380                        atype->type(),
00381                        atype->coord()));
00382 
00383       // -- Delete the old type...
00384       //delete atype;
00385     }
00386 
00387     // formals are not in scope yet; either
00388     //   1) this is only a function declaration, in which case the
00389     //      identifiers are only for documentation,  or
00390     //   2) this is part of a function definition, in which case the
00391     //      formal are not in scope until the upcoming function body.
00392     //      In this case, the formals are added by DefineProc just
00393     //      before the body is parsed.
00394 
00395     break;
00396   }
00397   */
00398 }
00399 
00400 declNode * declNode::set_type_and(typeNode * the_type, Storage_class sc, ScopeState redeclare)
00401 {
00402   set_type(the_type, sc, redeclare);
00403   return this;
00404 }
00405 
00406 declNode * declNode::set_type_and(declNode * the_decltype, Storage_class sc, ScopeState redeclare)
00407 {
00408   set_type(the_decltype->get_type(), sc, redeclare);
00409   //delete the_decltype;
00410   return this;
00411 }
00412 
00413 // ------------------------------------------------------------
00414 //  AppendDecl from complex-types.c
00415 //  Append decl adds decl to list, giving it the same type and declaration
00416 //  qualifiers as the decls already on list.
00417 // ------------------------------------------------------------
00418 
00419 void declNode::inherit_type(decl_list * others, ScopeState redeclare)
00420 {
00421   if (! others)
00422     return;
00423 
00424   declNode * first = others->front();
00425   typeNode * the_type = first->type()->deep_base_type();
00426   typeNode * copy = (typeNode *) ref_clone_changer::clone(the_type, false);
00427 
00428   set_type(copy, first->storage_class(), redeclare);
00429 
00430   decl_location(first->decl_location());
00431 }
00432 
00433 declNode * declNode::inherit_type_and(decl_list * others, ScopeState redeclare)
00434 {
00435   inherit_type(others, redeclare);
00436   return this;
00437 }
00438 
00439 // ------------------------------------------------------------
00440 //  SetDeclInit from complex-types.c
00441 // ------------------------------------------------------------
00442 
00443 void declNode::set_init(exprNode * new_init)
00444 {
00445   assert(init() == NULL);
00446 
00447   _init = new_init;
00448 
00449   if (new_init) {
00450     if (is_redundant_extern())
00451       // fix up misprediction made in SetDeclType.  
00452       //   decl has an initializer, so it isn't redundant.
00453       set_redundant_extern(false);
00454   }
00455 }
00456 
00457 declNode * declNode::set_init_and(exprNode * new_init)
00458 {
00459   set_init(new_init);
00460   return this;
00461 }
00462 
00463 // ------------------------------------------------------------
00464 // Data type base
00465 // ------------------------------------------------------------
00466 
00467 typeNode * declNode::base_type(bool TdefIndir) const
00468 {
00469   return type()->base_type(TdefIndir);
00470 }
00471 
00472 // ------------------------------------------------------------
00473 // Other queries
00474 // ------------------------------------------------------------
00475 
00476 typeNode * declNode::no_tdef_type()
00477 {
00478   return type()->follow_tdefs();
00479 }
00480 
00481 // ------------------------------------------------------------
00482 // Support for old-style declaration lists
00483 // ------------------------------------------------------------
00484 
00485 void declNode::add_parameter_types(decl_list * types)
00486 {
00487   funcNode * func = (funcNode *) type();
00488   assert(func->typ() == Func);
00489 
00490   func->add_parameter_types(types);
00491 }
00492 
00493 declNode * declNode::add_parameter_types_and(decl_list * types)
00494 {
00495   add_parameter_types(types);
00496   return this;
00497 }
00498 
00499 // --- Attributes
00500 
00501 void declNode::merge_attribs(attrib_list * attribs)
00502 {
00503   if (attribs) {
00504     _attribs.splice(_attribs.end(), * attribs);
00505     //delete attribs;
00506   }
00507 }
00508 
00509 // ------------------------------------------------------------
00510 //  Storage class and decl location
00511 // ------------------------------------------------------------
00512 
00513 string declNode::storage_class_name(Storage_class sc)
00514 {
00515   switch (sc) {
00516   case AUTO:     return string("auto");
00517   case EXTERN:   return string("extern");
00518   case REGISTER: return string("register");
00519   case STATIC:   return string("static");
00520   case TYPEDEF:  return string("typedef");
00521   default:
00522     return string("");
00523   }
00524 }
00525 
00526 string declNode::decl_location_name(Decl_location dl)
00527 {
00528   switch (dl) {
00529   case TOP:    return string("top");
00530   case BLOCK:  return string("block");
00531   case FORMAL: return string("formal");
00532   case SU:     return string("struct/union");
00533   case ENUM:   return string("enum");
00534   case PROC:   return string("proc");
00535   default: return string("unknown");
00536   }
00537 }
00538 
00539 // ------------------------------------------------------------
00540 //  Walker
00541 // ------------------------------------------------------------
00542 
00543 void declNode::visit(Visitor * the_visitor) 
00544 {
00545   the_visitor->at_decl(this);
00546 }
00547 
00548 void declNode::walk(Walker & the_walker)
00549 {
00550   Walker::Order ord = the_walker.order(); 
00551 
00552   if (ord == Walker::Preorder || ord == Walker::Both)
00553     the_walker.at_decl(this, Walker::Preorder);
00554 
00555   if (the_walker.depth() == Walker::Subtree) {
00556     // -- Visit the children 
00557 
00558     list_walker(pragmas(), the_walker);
00559 
00560     if (type())
00561       type()->walk(the_walker);
00562 
00563     if (init())
00564       init()->walk(the_walker);
00565 
00566     if (bitsize())
00567       bitsize()->walk(the_walker);
00568 
00569     list_walker(attribs(), the_walker);
00570   }
00571 
00572   if (ord == Walker::Postorder || ord == Walker::Both)
00573     the_walker.at_decl(this, Walker::Postorder);
00574 }
00575 
00576 // ------------------------------------------------------------
00577 //  Dataflow
00578 // ------------------------------------------------------------
00579 
00580 void declNode::dataflow(FlowVal * v, FlowProblem & fp)
00581 {
00582   if (fp.forward()) {
00583     fp.flow_decl(v, this, FlowProblem::Entry);
00584 
00585     if (init())
00586       init()->dataflow(v, fp);
00587 
00588     fp.flow_decl(v, this, FlowProblem::Exit);
00589   }
00590   else {
00591     fp.flow_decl(v, this, FlowProblem::Exit);
00592 
00593     if (init())
00594       init()->dataflow(v, fp);
00595 
00596     fp.flow_decl(v, this, FlowProblem::Entry);
00597   }
00598 }
00599 
00600 // ------------------------------------------------------------
00601 // Ouput
00602 // ------------------------------------------------------------
00603 
00604 void declNode::output(output_context & ct, Node * parent)
00605 {
00606   // -- First see if there are any pragma things to output. Right now, this
00607   // is only used to output the #includes.
00608 
00609   for (text_list_p p = pragmas().begin();
00610        p != pragmas().end();
00611        ++p)
00612     (*p)->output(ct, parent);
00613 
00614   // -- Now show the declaration
00615 
00616   Decl_location loc = decl_location();
00617 
00618   if (loc == ENUM)
00619     ct << name();
00620   else {
00621 
00622     if (loc != FORMAL)
00623       ct.new_line();
00624 
00625     ct << storage_class_name(storage_class());
00626     ct.space();
00627 
00628     type()->output_type(ct, this, Left, typeNode::NONE);
00629 
00630     if (! name().empty()) {
00631       ct.space();
00632       ct << name();
00633     }
00634 
00635     type()->output_type(ct, this, Right, typeNode::NONE);
00636   }
00637 
00638   if (init()) {
00639     ct.space();
00640     ct << '=';
00641     ct.space();
00642     init()->output(ct, this);
00643   }
00644 
00645   if (bitsize()) {
00646     ct.space();
00647     ct << ':';
00648     ct.space();
00649     bitsize()->output(ct, this);
00650   }
00651 
00652   if ((loc == TOP) ||
00653       (loc == BLOCK) ||
00654       (loc == SU) ||
00655       (loc == UNKNOWN) )
00656     ct << ';';
00657 }
00658 
00659 // ------------------------------------------------------------
00660 //  Changer
00661 // ------------------------------------------------------------
00662 
00663 Node * declNode::change(Changer & the_changer, bool redispatch)
00664 {
00665   Changer::Order ord = the_changer.order(); 
00666   declNode * the_decl = this;
00667 
00668   if ((ord == Changer::Preorder || ord == Changer::Both) && ! redispatch)
00669     the_decl = (declNode *) the_changer.at_decl(the_decl, Changer::Preorder);
00670 
00671   if (the_decl) {
00672 
00673     if (the_decl != this)
00674       return the_decl->change(the_changer, true);
00675 
00676     change_list(the_decl->pragmas(), the_changer);
00677 
00678     typeNode * old_type = the_decl->type();
00679     if (old_type) {
00680       typeNode * new_type = (typeNode *) old_type->change(the_changer);
00681       if (old_type != new_type) {
00682         //if (the_changer.delete_old())
00683          // delete old_type;
00684         the_decl->type(new_type);
00685       }
00686     }
00687 
00688     exprNode * old_init = the_decl->init();
00689     if (old_init) {
00690       exprNode * new_init = (exprNode *) old_init->change(the_changer);
00691       if (old_init != new_init) {
00692         //if (the_changer.delete_old())
00693          // delete old_init;
00694         the_decl->init(new_init);
00695       }
00696     }
00697 
00698     exprNode * old_bitsize = the_decl->bitsize();
00699     if (old_bitsize) {
00700       exprNode * new_bitsize = (exprNode *) old_bitsize->change(the_changer);
00701       if (old_bitsize != new_bitsize) {
00702         //if (the_changer.delete_old())
00703           //delete old_bitsize;
00704         the_decl->bitsize(new_bitsize);
00705       }
00706     }
00707 
00708     change_list(the_decl->attribs(), the_changer);
00709 
00710   }
00711 
00712   if ((ord == Changer::Postorder || ord == Changer::Both) && ! redispatch)
00713     the_decl = (declNode *) the_changer.at_decl(the_decl, Changer::Postorder);
00714 
00715   return the_decl;
00716 }
00717 
00718 
00719 // ------------------------------------------------------------
00720 // Destructor
00721 // ------------------------------------------------------------
00722 
00723 declNode::~declNode()
00724 {
00725   //delete _type;
00726   //delete _init;
00727   //delete _bitsize;
00728   //delete_list(_attribs);
00729 }

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